首页 > 解决方案 > 动态分配的 C 风格字符串的字符数超过给定长度?

问题描述

我正在使用动态 C 样式字符串从文件中读取数据,但由于某种原因,当我使用给定长度动态分配 C 样式字符串时,它会出现四个额外的字符,可以使用strlen(). 这些空白处的垃圾被添加到读入字符串的末尾,并显示在cout. 到底是什么导致了这种情况,我该如何解决?

C 风格的字符串在代码的开头声明,并在此之前使用一次。在此之前使用的时间也太大了,但在这种情况下,它不会在末尾添加额外的信息。使用后,将其删除,直到此时才再次使用。我很困惑,因为我以前没有发生过这种情况或遇到过问题。

// Length read as 14, which is correct
iFile.read(reinterpret_cast<char *>(&length), sizeof(int)); 

tempCstring = new char[length]; // Length still 14
cout << strlen(tempCstring); // Console output: 18

// In tempCstring: Powerful Blockýýýý
iFile.read(reinterpret_cast<char *>(tempCstring), length);

// Custom String class takes in value Powerful Blockýýýý and is 
// initialized to that
tempString = String(tempCstring);

// Temp character value takes in messed up string
temp.setSpecial(tempString); 
delete[] tempCstring; // Temp cString is deleted for next use

写入文件时:

// Length set to the length of the cString, m_special
length = strlen(chars[i].getSpecial().getStr());

// Length written to file. (Should I add 1 for null terminator?)
cFile.write(reinterpret_cast<char *>(&length), sizeof(int));

// String written to file
cFile.write(reinterpret_cast<char *>(chars[i].getSpecial().getStr()), length);

标签: c++arraysfilec-strings

解决方案


每当您在字符串末尾看到垃圾时,问题几乎总是缺少终止符。每个 C 风格的字符串都以一个值为 0 的字节结尾,拼写为'\0'. 如果您自己没有放置一个,标准库会一直读取内存中的字节,直到它看到'\0'它在内存中看到的随机数。换句话说,数组的读取超出了它的范围。

用于memset(tempCString,0,length)在分配后将内存清零。然而,这并不是最合理的解决方案,因为它掩盖了真正的问题。向我们展示使用此代码的上下文。然后我将能够说明您需要在算法中的哪个位置插入空终止符:tempCString[i] = 0或类似的东西。尽管如此,从您发布的内容来看,我可以告诉您需要再分配一个角色来为终结者腾出空间。

另外,既然您使用的是 C++,为什么不使用std::string? 它避免了这类问题。


推荐阅读