我不确定我明白下面的错误是什么
const char* packs[] = {"zero","one","two","three","four",..."twelve"} //abbreviated for post
struct packinfo {
char* data;
int len;
};
std::vector<packinfo> k;
k.reserve(10000);
for (int i = 0; i < 10; ++i) {
const char* data = packs[i];
packinfo tobuf;
tobuf.data = new char[strlen(data)];
tobuf.len = strlen(data);
memcpy(tobuf.data, data, strlen(data));
k.push_back(tobuf);
}
for (int i = 0; i < k.size(); ++i)
std::cout << "k[" << i << "]: " << k[i].data << ", ";
std::cout << std::endl;
for (int i = 0; i < k.size(); ++i) {
packinfo& pack = k[i];
bool foo = (i < 5);
if (foo) std::cout << "inspecting k[" << i << "]: " << k[i].data << std::endl;
delete pack.data;
if (!foo) {
k.erase(k.begin(), k.begin() + i);
packinfo tobuf;
const char* data = packs[10];
tobuf.data = new char[strlen(data)];
tobuf.len = strlen(data);
memcpy(tobuf.data, data, strlen(data));
break; //intentionally forgot to push_back
}
}
for (int i = 0; i < k.size(); ++i)
std::cout << "k[" << i << "]: " << k[i].data << ", ";
std::cout << std::endl
运行上述内容的输出如下:
k[0]: zero, k[1]: one, ... , k[9]: nine, //all as expected
inspecting k[0]: zero
inspecting k[1]: one
...
inspecting k[4]: four
k[0]: ten^], k[1]: six, k[2] seven, k[3]: eight, k[4]L nine, //gargabe crept in
垃圾如何蔓延到载体的开头?
答案 0 :(得分:3)
strlen
为您提供以空终止字符串的字符长度,而不计算nul-termination字符。因此,您正在动态分配一个太短而无法容纳目标字符串的数据缓冲区:
tobuf.data = new char[strlen(data)]; // too short by 1
当你使用memcpy填充它时,字符串的空终止没有空间,如果有的话你也不会复制它,因为数组太短了:
memcpy(tobuf.data, data, strlen(data)); // tobuf.data is not nul-terminated
当你试图读取它就好像它是一个以空字符串结尾的字符串时,你就会超出界限。
立即修复将使用strlen(data) +1
,但您真正应该做的是将packinfo
替换为std::string
来避免整个问题。
std::vector<std::string> k;
k.reserve(10000);
答案 1 :(得分:1)
问题在于以下几点:
tobuf.data = new char[strlen(data)];
tobuf.len = strlen(data);
memcpy(tobuf.data, data, strlen(data));
在哪里为字符串终止符添加空间?
C ++有std::string
类,你应该真正使用它,因为它可以帮助你解决这些问题。