简体   繁体   English

动态分配的C样式字符串具有比给定长度更多的字符?

[英]Dynamically allocated C-style string has more characters than given length?

I'm using a dynamic C-style string to read in data from a file, but for some reason when I dynamically allocate the C-style string using the given length, it comes out with four extra characters that can be seen using strlen() . 我正在使用动态C样式字符串从文件中读取数据,但是由于某些原因,当我使用给定的长度动态分配C样式字符串时,它带有四个额外的字符,可以使用strlen() The junk in these empty spaces is added on to the end of the read-in string and is displayed on cout . 这些空白处的垃圾会添加到读入字符串的末尾,并显示在cout What on earth could be causing this, and how can I fix it? 到底是什么引起的,我该如何解决?

The C-style string is declared in the beginning of the code, and is used one time before this. C样式的字符串在代码的开头声明,并且在此之前使用过一次。 The time it is used before this it is also too large, but in that case it does not add extra information to the end. 在此之前使用它的时间也太大,但是在那种情况下,它不会在末尾添加额外的信息。 After use, it is deleted and not used again until this point. 使用后,将其删除,直到此刻才再次使用。 I'm pretty confused as I have not had this happen or had a problem with it before. 我很困惑,因为我以前没有发生过或有问题。

// 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

When written to file: 写入文件时:

// 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);

Whenever you see junk at the end of a string, the problem is almost always the lack of a terminator. 每当您在字符串的末尾看到垃圾时,问题几乎总是缺少终结符。 Every C-style string ends in a byte whose value is zero, spelled '\\0' . 每个C风格的字符串都以一个值为0的字节结尾,拼写为'\\0' If you did not place one yourself, the standard library keeps reading bytes in memory until it sees a random '\\0' that it sees in memory. 如果您自己没有放置,则标准库将继续读取内存中的字节,直到在内存中看到随机的'\\0' In other words, the array is read beyond its bounds. 换句话说,数组的读取超出其范围。

Use memset(tempCString,0,length) in order to zero out the memory following your allocation. 使用memset(tempCString,0,length)以便在分配memset(tempCString,0,length)内存清零。 However, this is not the soundest solution, as it is covering the real problem under the rug. 但是,这不是最合理的解决方案,因为它涵盖了地毯下的实际问题。 Show us the context in which this code is used. 向我们展示使用此代码的上下文。 Then I will be able to say where in your algorithm you will need to insert the null terminator: tempCString[i] = 0 , or something like that. 然后,我可以说出您需要在算法的哪个位置插入空终止符: tempCString[i] = 0或类似的东西。 Nonetheless, from what you have posted, I can tell that you need to allocate one more character to make room for the terminator. 但是,从您发布的内容来看,我可以告诉您需要再分配一个字符来为终止符腾出空间。

Also, since you are using C++, why not use std::string ? 另外,由于您使用的是C ++,为什么不使用std::string呢? It avoids these kinds of problems. 它避免了这类问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM