遗憾的是,我无法弄清楚c ++这样的基本内容,但c风格的字符串正如我所预料的那样。例如,我创建它像这样:
char* cstr = new char[1];
它被初始化为:Íýýýýý«««««««««îţ。像往常一样,我可以设置第一个char,因为其他人并不存在(或者我认为它们不存在)。在使用白色c风格的字符串时,所有这些垃圾都会被嵌入,一切正常。
现在我混合了std :: string whit那些c-stlye,我得到的是一团糟。使用此代码:
std::string str = "aaa";
str += cstr;
我结束了自己:aaaÍýýýýý««««««««îţ,但现在这些字符实际存在,因为string.size()返回长度,包括这个垃圾。
我找不到为什么会发生这种情况,但必须连接whit string创建,因为像char * cstr =“aaa”这样的东西导致aaa没有任何额外的垃圾,但尝试更改字符串初始化这种方式会导致内存访问冲突。有人能解释一下这种行为吗?谢谢!
PS:我的JavaScript无法加载,所以如果有人可以正确格式化这篇文章,我会很高兴的!
答案:天啊!我怎么能忘记这一点...感谢所有的,好的,立即回答。最好的一个来自minitech所以我会在我的java脚本加载时将其标记为答案:/
答案 0 :(得分:6)
所有C风格的字符串都以空值终止。因此,使用new char[1]
初始化的字符串会为您留下没有字符的空间。您不能将第一个字符设置为除\0
之外的任何字符,否则正常的字符串操作将一直读入内存,直到它们找到零。所以请改用new char[2]
。
答案 1 :(得分:5)
使用C风格的字符串时,需要使用空终止符:
char* cstr = new char[2];
cstr[0] = 'X';
cstr[1] = '\0';
说了这么多,上面的代码真的很糟糕。只要使用std::string
,除非你有充分的理由。它会为您处理内存分配和解除分配。
答案 2 :(得分:2)
C风格的字符串需要NUL
('\0'
)终止符;他们没有与C ++字符串相关的长度。所以你的单字符串必须是new char[2]
;它不会被初始化;并且您需要确保它以\0
终止。
答案 3 :(得分:1)
使用new char[1]
时,请求字符数组的空间。没有要求所述字符被初始化。因此,你看到的“垃圾”是未初始化的记忆。在将数组视为C风格的字符串之前,您应该这样做:
cstr[0] = '\0';
答案 4 :(得分:1)
c样式字符串以NULL分隔。因此,要忽略内存中的任何垃圾,您需要在字符串体中放置NULL字节('\0'
)。否则,系统库函数将查看以字符串start开头的所有字节,直到它们在内存中遇到NULL字节(将在某个随机位置)。
这也意味着要拥有一个字符的c样式字符串,实际上需要分配2个字节:一个用于有意义的字符,第二个用于'\0'
。