(为什么)空字符串有地址?

时间:2011-08-23 02:04:17

标签: c++

我猜不是,但这样的输出显示它确实

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

拥有地址的空字符串有什么意义? 你认为不应该花费任何记忆吗?

7 个答案:

答案 0 :(得分:22)

是的,您保存在内存中的每个变量都有一个地址。至于“点”是什么,可能有几个:

  1. 你的(文字)字符串实际上并不是“空”,它包含一个'\ 0'字符。为包含它而创建的std::string对象可以分配自己的字符缓冲区来保存这些数据,因此它也不一定是空的。
  2. 如果您使用的字符串是可变的语言(如C ++中的情况),则无法保证空字符串将保持为空。
  3. 在面向对象的语言中,没有与之关联的数据的字符串实例仍可用于调用字符串类上的各种实例方法。这需要内存中的有效对象实例。
  4. 空字符串与null字符串之间存在差异。有时这种区别很重要。
  5. 是的,我非常同意语言的实现,即“空”变量应该仍然存在并消耗内存。在面向对象的语言中,对象的实例不仅仅是它存储的数据,而且拥有一个当前没有存储任何实际数据的对象实例也没有错。

答案 1 :(得分:6)

遵循您的逻辑,int i;也不会分配任何内存空间,因为您没有为其分配任何值。但是,那么后续的操作i = 10;怎么可能呢?

声明变量时,实际上是在分配一定大小的内存空间(取决于变量的类型)来存储某些内容。如果您想以正确的方式使用此空间取决于您,但变量的声明是触发内存分配的原因。

某些编码实践表明,在您需要使用它之前,不应声明变量。

答案 2 :(得分:5)

'empty'字符串对象仍然是一个对象 - 它的内部实现可能不仅仅是存储文字字符串本身所需的内存。除此之外,大多数C风格的字符串(如C ++中使用的字符串)都是以空值终止的,这意味着即使“空”字符串仍然使用一个字节作为终结符。

答案 3 :(得分:3)

sstring对象,因此它有一个地址。它有一些内部数据结构跟踪字符串。例如,字符串的当前长度,为字符串保留的当前存储等

更一般地说,C ++标准要求所有对象都具有非零大小。这有助于确保 每个对象都有唯一的地址

  

9个课程

     

类类型的完整对象和成员子对象应具有非零大小。

答案 4 :(得分:3)

C ++中的每个命名对象都有一个地址。甚至有一个特定的要求,即每种类型的大小至少为1,以便T[N]T[N+1]不同,或者在T a, b;中,两个变量都有不同的地址。

在您的情况下,sstd::string类型的命名对象,因此它有一个地址。您从特定值构造s的事实并不重要。重要的是s 已经构建了,所以它是一个对象,所以它有一个地址。

答案 5 :(得分:2)

在C ++中,所有类都是特定的,不变的大小。 (由编译器和库改变,但在编译时具体。)std :: string通常由指针,分配长度和使用的长度组成。这是~12个字节,无论字符串有多长,并且您在调用堆栈上分配了std :: string。当你显示std :: string的地址时,cout会在内存中显示std :: string的位置。

如果字符串没有指向任何东西,它将不会从堆中分配任何空间,这就像你在想的那样。但是,所有c字符串都以尾随NULL结尾,因此c字符串“”是一个字符长,而不是零。这意味着当您将c-string“”分配给std :: string时,std :: string将分配1个(或更多)字节,并为其分配尾随NULL字符的值(通常为零'\ 0')。

答案 6 :(得分:2)

如果确实没有指向空字符串,那么程序员根本不会写指令。这种语言是忠诚和信任的!永远不会假设你分配的内存被“浪费”。即使你迷路并越过悬崖,它也会把你的手伸向痛苦的结局。

我认为有趣的是,作为一种好奇心,如果你创建一个之后没有'使用'的变量,比如你的空字符串,编译器可以很好地优化它,所以它开始时不会产生任何费用。我猜编译器不是那么信任......