2011-06-04 29 views
2

的这是一个耻辱,我无法弄清楚这些基本的东西对C++的,但C风格的字符串作为我不会期望。例如,我创造这样的: char* cstr = new char[1];单个字符C风格串满垃圾

它初始化为:Íýýýýý««««««««它。正常情况下,我可以设置第一个字符,因为其他字符不是真正存在的(或者我认为它们不是)。在工作时使用白色c风格的字符串,所有这些垃圾都可以使用,并且一切正常。

现在我是混合性的std :: string白衣的C-stlye一个和我所得到的是一个烂摊子。惠特此代码:

std::string str = "aaa";

str += cstr;

我结束了白衣:aaaÍýýýýý««««««««它,但现在这些字符实际存在的string.size()返回长度,包括这个垃圾。

我找不到为什么会发生这种情况,但它必须连接whit字符串创建,因为类似char * cstr =“aaa”会导致aaa没有任何额外的垃圾,但尝试更改字符串初始化这种方式结果在内存访问冲突。有人能解释我这种行为吗?谢谢!

PS:我的JavaScript无法加载,所以如果有人能正确地格式化这个职位,我会很高兴!

答:哦,上帝​​!我怎么能忘记这一点......感谢所有人,好吧,立即回答。最好的一个来自minitech,所以我将这个标记作为答案,只要我的Java脚本加载:/

回答

6

所有的C风格的字符串是空终止的。所以,使用new char[1]初始化一个字符串会留下空间来放置任何字符。除了\0之外,您不能将第一个字符设置为任何内容,否则正常的字符串操作会一直读到内存中直到找到零。所以请使用new char[2]

1

当您使用new char[1]时,您请求一个字符数组的空间。没有要求所述字符被初始化。因此,您看到的“垃圾”是未初始化的内存。在将数组视为C风格的字符串之前,应该这样做:

cstr[0] = '\0'; 
1

c样式的字符串是NULL定界的。因此,要忽略内存中的任何垃圾,您需要将空字节('\0')置于字符串正文中。否则,系统库函数将查看以字符串开始开始的所有字节,直到它们在内存中满足NULL字节(它将位于某个随机位置)。

这也意味着要实际需要分配2个字节的一个字符的c样式字符串:一个用于有意义的字符,另一个用于'\0'

2

C风格串需要NUL'\0')终止子;它们没有像C++字符串那样的长度。所以你的单字符串必须是new char[2];它不会被初始化;你将需要确保它以\0终止。

5

与C风格字符串的工作,你需要有一个空终止:

char* cstr = new char[2]; 
cstr[0] = 'X'; 
cstr[1] = '\0'; 

说了这么多,这是非常糟糕的代码做以上。除非你有一个非常好的理由,否则请使用std::string。它负责为你分配和释放内存。