当我遇到奇怪的字符串转换时,我发现不同的字符串变量指向相同的地址。
我在样本中制作了3个字符串变量。我认为a和b应该指向相同的地址,因为b是a的引用变量。
但是变量c也指向与a和b相同的地址。我不明白这个......
如果你给我任何建议,我真的很感激。
问题:
为什么a,b和c变量指向相同的地址?
更改后" c [2]"值,c改为指向不同的地址。你能解释一下吗?
两个approches有什么区别?
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
答案 0 :(得分:2)
首先,您必须了解参考。引用基本上是其他东西的别名。初始化b
作为对a
的引用后,b
实际上是a
的别名,当您使用b
编译器时(以某种方式) )将其翻译为a
。
至于为什么地址相同,它可能只是编译器和标准库的优化。 a
和c
都被初始化为相同的内容,为什么不共享内容?节省内存。修改字符串后,它会将字符串复制到自己的内存中。
至于您对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的数据部分中没有创建实际内存;相反,b
是a
的别名。
说到c
,您有创建了实际内存,并在a
中为其分配了数据:
std::string c;
c = b;
因此,c
将具有与a
不同的内存地址。 b
的地址与a
的地址相同。
答案 3 :(得分:0)
std :: strings被重新计算,通常在你修改时就会发生写入副本。这就是为什么地址变化