1

Code:

#include <iostream>
#include <string>

int main(void)
{

    std::cout << "Please enter your name: ";
    std::string name;
    std::cin >> name;

    std::cout << std::endl;

    std::cout << "Your name is " << name << "." << std::endl;

    std::cout << "The size of '" << name << "' in bytes is " << sizeof(name)
    << "." << std::endl;

    std::cin.get();
    std::cin.get();

    return 0;
}

Question

Whenever I run this program, and input a string for the variable 'name', It will always output that the size of the variable is 32 bytes. This seems rather large for a four or perhaps five character name. Is it something to do with the O/I stream? Or does it have to do with something in the string class? I'm new to C++ so any help is appreciated. Thanks.

Output for the program:

Please enter your name: Jake

Your name is Jake. The size of 'Jake' in bytes is 32.

Jake2k13
  • 231
  • 3
  • 8
  • 23
  • The size has nothing to do with what you enter. The size of the object must be known at compile time. – chris Dec 20 '13 at 04:24
  • When I run your code, it printed out 4. I run with gcc 4.7. – Deidrei Dec 20 '13 at 04:25
  • So unless the string is assigned explicitly, it will remain 32 bytes? Is that correct? @chris – Jake2k13 Dec 20 '13 at 04:25
  • @Jake2k13, Being assigned to is done at runtime. – chris Dec 20 '13 at 04:28
  • @Jake2k13: The result of `sizeof` has no connection to the actual string value stored in `std::string`, regardless of when or how it is assigned. In your case `sizeof` of `std::string` object will always evaluate to 32 regardless of what you do with it. You can store Shakespeare's "Hamlet" in your string, but `sizeof` will still be 32. Stop trying to use `sizeof` for that purpose. It does not do what you think it does. – AnT stands with Russia Dec 20 '13 at 04:35
  • @AndreyT, Great to know, but how come it is 32 bytes exactly? – Jake2k13 Dec 20 '13 at 04:36
  • @Jake2k13: plz refer to Floris link. – Deidrei Dec 20 '13 at 04:37
  • 1
    @Jake2k13: In your implementation of standard library `std::string` object contains some implementation-specific internal data fields (pointers, integers, etc.). The total size of those internal data fields, plus possible padding, just happens to be 32 bytes. That's all there is to it. In some other implementation it might be 16, or 8 or 42. It can be anything. It is implementation-specific. Typically you are not supposed to care about the exact value. If you really care to know why it is 32 specifically, open your standard library header and see what's inside `std::string`. – AnT stands with Russia Dec 20 '13 at 04:38

2 Answers2

7

sizeof is a compile time operator which returns the size in bytes of an object representation, which is the size of its layout in memory. It has nothing to do with the std::string content.

Use string.size() instead.

Casey
  • 41,449
  • 7
  • 95
  • 125
Jack
  • 131,802
  • 30
  • 241
  • 343
  • it should probably be string.size() * sizeof(char) since he wants it in bytes. – pstrjds Dec 20 '13 at 04:27
  • 1
    @pstrjds, `sizeof(char)` is always 1. – chris Dec 20 '13 at 04:28
  • 1
    @pstrjds: ISO/IEC guarantees that `sizeof(char) == 1`. §5.3.3: __sizeof(char), sizeof(signed char) and sizeof(unsigned char) are 1__ – Jack Dec 20 '13 at 04:29
  • @chris, I agree. A size of a char in bits is of course 8, right? – Jake2k13 Dec 20 '13 at 04:30
  • @Jake2k13, It's `CHAR_BIT` bits. Yes, there are, from what I recall, actual 5-bit, 7-bit, and 32-bit per byte machines. Any of those could be complete BS, but it shouldn't be too hard to find real examples. – chris Dec 20 '13 at 04:30
  • @chris - True - I guess I was over thinking it so that the code could be easily modified if OP switched to std::wstring's or other wide character strings in the future. – pstrjds Dec 20 '13 at 04:30
  • @Chris, well assuming it's encoded in ASCII, it would be 8 – Jake2k13 Dec 20 '13 at 04:31
  • 2
    @pstrjds, In that case, `sizeof(decltype(name)::value_type)`. – chris Dec 20 '13 at 04:32
  • @chris - Excellent - and much cleaner +1 on your comment from me :) – pstrjds Dec 20 '13 at 04:33
  • 1
    @Jake2k13, Actually, ASCII is 7 bits. It's really more how many bits in a byte, though. `sizeof(char)` is one byte. How many bits is implementation-defined, and given by `CHAR_BIT`. You can see [this question](http://stackoverflow.com/questions/3200954/what-is-char-bit) for more. And it seems I forgot it has to be >= 8, sorry. – chris Dec 20 '13 at 04:33
  • I was just assuming when using sizeof(string) (assuming the string said jake), that it would return 4 bytes because in binary, 01001010 01100001 01101011 01100101 = 4 bytes (32 bits). I'm just so confused on this matter still. – Jake2k13 Dec 20 '13 at 04:39
  • @Jake2k13, If you ever look into how `std::string` works (NOT the optimizations, just a basic crappy string), you'll see it uses a pointer to the actual string because that pointer can be allocated memory and resize that memory and everything that makes us happy. The size of that pointer is always constant (probably 4 or 8). What it points to doesn't matter. – chris Dec 20 '13 at 04:39
  • Ok, @chris, so for this example would I pass the variable 'name' as an argument to std::string.size()? – Jake2k13 Dec 20 '13 at 04:43
  • 1
    @Jake2k13, Yes, that will give you the number of characters, but `name` is passed implicitly when you do `name.size()`. – chris Dec 20 '13 at 04:45
3

std::string consists of two parts:

  • The content of the string, which is allocated dynamically, and can grow or shrink based on the actual size, and
  • A fixed-footprint object that contains the "anchor" of the string through which you access the content.

When you access sizeof(name), you get the size of the fixed "anchor" portion. If you would like to find the length, call name.length() or name.size(). If you would like to know an approximate lower bound of the footprint of your string, add sizeof(name) + name.size() + 1. The actual footprint may be larger, because the dynamic portion may have more space than is actually used. In some implementations, the footprint of very short strings that fit entirely in the fixed portion of std::string may be equal to sizeof(name).

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523