不同的字符串变量点同一地址

时间:2016-01-14 07:13:53

标签: c++ string stl

当我遇到奇怪的字符串转换时,我发现不同的字符串变量指向相同的地址。

我在样本中制作了3个字符串变量。我认为a和b应该指向相同的地址,因为b是a的引用变量。

但是变量c也指向与a和b相同的地址。我不明白这个......

如果你给我任何建议,我真的很感激。

问题:

  1. 为什么a,b和c变量指向相同的地址?

  2. 更改后" c [2]"值,c改为指向不同的地址。你能解释一下吗?

  3. 两个approches有什么区别?

  4.   

    c [2] =' z';

         

    //变量c改变了值,但地址仍然相同。

         

    char temp =(char )c.c_str(); temp [2] =' z';

    编译器版本: g ++(GCC)4.4.7 20120313(Red Hat 4.4.7-11)

    编译选项: g ++ -o test test.c

    这是我的代码。

    => (def o (Event.))
    => (call-method* o "setA" "1")
    CompilerException java.lang.RuntimeException: Can't embed object in code,  
    maybe print-dup not defined: mytest.Event@681d891, compiling:   
     (/private/var/folders/hd/xxl2lfmn5wggspxwwtk2r2zr0000gn/T/form-init2883112335729429073.clj:1:1)
    

    结果:

    [a] value = ab; cd; ef; gh,address = 0x705028

    [b] value = ab; cd; ef; gh,address = 0x705028

    [c] value = ab; cd; ef; gh,address = 0x705028

    [a] value = ab; cd; ef; gh,address = 0x705028

    [b] value = ab; cd; ef; gh,address = 0x705028

    [c] value = abzcd; ef; gh,address = 0x705058

4 个答案:

答案 0 :(得分:2)

首先,您必须了解参考。引用基本上是其他东西的别名。初始化b作为对a的引用后,b实际上是a的别名,当您使用b编译器时(以某种方式) )将其翻译为a

至于为什么地址相同,它可能只是编译器和标准库的优化。 ac都被初始化为相同的内容,为什么不共享内容?节省内存。修改字符串后,它会将字符串复制到自己的内存中。

至于您对temp的使用,这是非常错误的,并导致未定义的行为。来自this c_str reference

  

写入通过c_str()访问的字符数组是未定义的行为。

c中的c_str代表常量(即只读)。你需要使用C风格的演员表明你做的事情可能是危险的,而且往往很糟糕。

答案 1 :(得分:0)

b是对a的引用。因此,b.c_str()a.c_str()必须返回相同的指针值。

c.c_str()只有在出于效率原因指向相同数据的情况下才会返回与a.c_str()相同的值。

看起来std::string的g ++实现使用引用计数数据。那么,只有在修改数据时才会复制数据。

来自文件basic_string.h:

*                                        [_Rep]
*                                        _M_length
*   [basic_string<char_type>]            _M_capacity
*   _M_dataplus                          _M_refcount
*   _M_p ---------------->               unnamed array of char_type

答案 2 :(得分:0)

As Joachim Pileborg said,您已将b创建为别名自动参考

因此,无论何时使用b,您都使用a

对于b ,在RAM的数据部分中没有创建实际内存;相反,ba的别名。

说到c,您有创建了实际内存,并在a中为其分配了数据:

std::string c;
c = b;

因此,c将具有与a不同的内存地址。 b的地址与a的地址相同。

答案 3 :(得分:0)

std :: strings被重新计算,通常在你修改时就会发生写入副本。这就是为什么地址变化