c++ - 动态分配的 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 风格的字符串都以一个值为 0 的字节结尾,拼写为'\0'
. 如果您自己没有放置一个,标准库会一直读取内存中的字节,直到它看到'\0'
它在内存中看到的随机数。换句话说,数组的读取超出了它的范围。
用于memset(tempCString,0,length)
在分配后将内存清零。然而,这并不是最合理的解决方案,因为它掩盖了真正的问题。向我们展示使用此代码的上下文。然后我将能够说明您需要在算法中的哪个位置插入空终止符:tempCString[i] = 0
或类似的东西。尽管如此,从您发布的内容来看,我可以告诉您需要再分配一个角色来为终结者腾出空间。
另外,既然您使用的是 C++,为什么不使用std::string
? 它避免了这类问题。
推荐阅读
- javascript - 如何检查2个正则表达式是否相同的会计语法差异?
- java - 在android studio中获取连接被拒绝(连接被拒绝)
- javascript - 使用 d3.drag 时,剪辑路径与元素组一起移动
- java - 如何输入句点作为小数点?
- ios - 使用 SwiftUI 添加谷歌登录
- c# - 如何注销除当前登录用户之外的所有 Windows 10 用户?
- javascript - 我无法显示我从 api 查找的结果,TypeError: undefined is not a function (near '... this.state.fantasyName.map ...')
- c# - 在 asp.net core 2.2 中使用远程验证的问题
- c++ - 程序在遍历所有值之前离开循环
- firebase - 索引数据是否计入 Cloud Firestore 中的免费套餐数据配额?