14

I guessed no, but this output of something like this shows it does

string s="";
cout<<&s;

what is the point of having empty string with an address ? Do you think that should not cost any memory at all ?

Catskul
  • 17,916
  • 15
  • 84
  • 113
Baby Dolphin
  • 489
  • 4
  • 13
  • 1
    @wilhelmtell, that is not relevant here. std::string is not an "empty" class. It has data members. – Catskul Aug 23 '11 at 03:43
  • String _literals_ may overlap in memory, and the empty string can overlap any other string. So even if `""` has an address, it may not be a unique one. `&s` is another matter. – MSalters Aug 23 '11 at 08:49
  • @Catskul that is very, very relevant here. It's not a duplicate, it's _relevant_. It talks about the idea of something in C++ having no address, why it's wrong, when you might think it's true and why even then it isn't. An empty string is just coming back to the same discussion with a different concrete case. – wilhelmtell Aug 23 '11 at 15:52
  • @wilhelmtell, the answer to the linked question is relevant, but the linked question itself is not. If you are going to be terse, don't be surprised when people don't correctly read your mind. – Catskul Aug 23 '11 at 16:22

7 Answers7

23

Yes, every variable that you keep in memory has an address. As for what the "point" is, there may be several:

  1. Your (literal) string is not actually "empty", it contains a single '\0' character. The std::string object that is created to contain it may allocate its own character buffer for holding this data, so it is not necessarily empty either.
  2. If you are using a language in which strings are mutable (as is the case in C++), then there is no guarantee that an empty string will remain empty.
  3. In an object-oriented language, a string instance with no data associated with it can still be used to call various instance methods on the string class. This requires a valid object instance in memory.
  4. There is a difference between an empty string and a null string. Sometimes the distinction can be important.

And yes, I very much agree with the implementation of the language that an "empty" variable should still exist in and consume memory. In an object-oriented language an instance of an object is more than just the data that it stores, and there's nothing wrong with having an instance of an object that is not currently storing any actual data.

aroth
  • 54,026
  • 20
  • 135
  • 176
  • 1
    Thank you, 4. What is the difference between an empty string and a null string ? – Baby Dolphin Aug 23 '11 at 02:36
  • 2
    An empty string doesn't necessarily contain a NULL. In fact, std::string can hold NULLs anywhere within the string. – wilhelmtell Aug 23 '11 at 02:40
  • Thanks a lot. By the way I upvote all joiners 1 as I find your replies are useful, I don't know which I should choose as an accepted answer. Again, Thanks everyone. – Baby Dolphin Aug 23 '11 at 02:50
  • 4
    @wilhelmtell: `NULL` is a macro that expands to a null *pointer* constant. It should not be used to refer to the null character (NUL, `'\o'`). – Keith Thompson Aug 23 '11 at 03:46
  • @Keith you're right. But in practice `NULL` is `0` or `0L`, and `\0` is `(char)0`, so the cast should be well defined. Of course, in older compilers `NULL` might be `(void*)(0)` or something of this order of insanity. At any rate, you're right, `\0` expresses the right thing here whereas `NULL` talks about something else. But at the same time, prior to C++11 we were using `0` for the null pointer, and `0` is an integer, not a pointer. So I'm going to use that as my excuse. :) – wilhelmtell Aug 23 '11 at 15:47
  • 1
    @wilhelmtell: Would you write `char* ptr = L'\0'`;? – Keith Thompson Aug 23 '11 at 15:54
6

Following your logic, int i; would also not allocate any memory space, since you are not assigning any value to it. But how is it possible then, that this subsequent operation i = 10; works after that?

When you declare a variable, you are actually allocating memory space of a certain size (depending on the variable's type) to store something. If you want to use this space right way or not is up to you, but the declaration of the variable is what triggers memory allocation for it.

Some coding practices say you shouldn't declare a variable until the moment you need to use it.

karlphillip
  • 92,053
  • 36
  • 243
  • 426
  • When you say `std::string s;`, this does not put `s` in an uninitialized state, on the contrary. And when you later say `s = "long string";`, you don't suddenly start using the memory; rather, you've always been using it. The actual character data doesn't go inside the string object. – Kerrek SB Aug 23 '11 at 02:25
  • `int i;` is actually definition instead of declaration, while `extern int i;` declares. And declaration will not allocate memory. – Summer_More_More_Tea Aug 23 '11 at 02:27
  • The core of the problem is that the OP doesn't know what declaring a variable does. – karlphillip Aug 23 '11 at 02:56
  • The OP's example is more like `int i = 0;`. – dan04 Aug 23 '11 at 11:04
5

An 'empty' string object is still an object - there may be more to its internal implementation than just the memory required to store the literal string itself. Besides that, most C-style strings (like the ones used in C++) are null-terminated, meaning even that "empty" string still uses one byte for the terminator.

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
3

s is a string object so it has an address. It has some internal data structures keeping track of the string. For example, current length of the string, current storage reserved for string, etc.

More generally, the C++ standard requires all objects to have a nonzero size. This helps ensure that every object has a unique address.

9 Classes

Complete objects and member subobjects of class type shall have nonzero size.

Community
  • 1
  • 1
Eric Z
  • 14,327
  • 7
  • 45
  • 69
  • 1
    I don't think so. AFAIK there's nothing in the standard that says an `std::string` needs to be null terminated. The class only needs to return a null terminated string when `std::string::c_str` is called. – Praetorian Aug 23 '11 at 02:09
3

Every named object in C++ has an address. There is even a specific requirement that the size of every type be at least 1 so that T[N] and T[N+1] are different, or so that in T a, b; both variables have distinct addresses.

In your case, s is a named object of type std::string, so it has an address. The fact that you constructed s from a particular value is immaterial. What matters is that s has been constructed, so it is an object, so it has an address.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
2

In C++, all classes are a specific, unchanging size. (varying by compiler and library, but specific at compile-time.) The std::string usually consists of a pointer, a length of allocation, and a length used. That's ~12 bytes, no matter how long the string is, and you have allocated std::string s on the call stack. When you display the address of the std::string, cout displays the location of the std::string in memory.

If the string doesn't point at anything, it won't allocate any space from the heap, which is like what you're thinking. But, all c-strings end in a trailing NULL, so the c-string "" is one character long, not zero. This means when you assign the c-string "" to the std::string, the std::string allocates 1 (or more) bytes, and assigns it the value of the trailing NULL character (usually zero '\0').

Mooing Duck
  • 64,318
  • 19
  • 100
  • 158
2

If there truly was no point to the empty string, then the programmer would not write the instruction at all. The language is loyal and trusting! And will never assume memory you allocate to be "wasted". Even if you are lost and heading over a cliff, it will hold your hand to the bitter end.

I think it'd be interesting to know, just as a curiosity though, that if you create a variable that isn't 'used' later, such as your empty string, the compiler may very well optimize it away so it incurs no cost to begin with. I guess compilers aren't as trusting...

Anne Quinn
  • 12,609
  • 8
  • 54
  • 101