【发布时间】:2013-09-01 04:32:48
【问题描述】:
我使用动态分配的数组在 c++ 中为双精度序列编写了一个类。运行程序时,它成功完成,但 valgrind 发现错误。调用我的调整大小函数时,我收到大小为 8 的无效读取。
void sequence::resize(size_type new_capacity){
if (new_capacity == capacity){
return;
}else {
if (new_capacity < used)
used = new_capacity;
capacity = new_capacity;
value_type* new_vals;
new_vals = new value_type[capacity];
for (int i=0;i<used;i++){
new_vals[i] = data[i];
}
cout<<endl;
delete [] data;
data = new_vals;
}
}
附加正在调用调整大小:
void sequence::attach(const value_type& entry){
//Behaivoir for empty sequence
if(used == 0){
current_index = 0;
used++;
if (used > capacity)
resize(capacity*2);
data[current_index] = entry;
}
//Behaivoir for no current_index
else if (!is_item()){
current_index = used;
used++;
if (used > capacity)
resize(capacity*2);
data[current_index] = entry;
}
//Default behaivoir
else {
used++;
if (used > capacity)
resize(capacity*2);
for(int i = used-1; i>current_index+1;i--)
data[i] = data[i-1];
advance();
data[current_index] = entry;
}
}
这是我在测试程序中收到的错误:
==1919== Invalid read of size 8
==1919== at 0x400DB3: main_savitch_4::sequence::resize(unsigned long) (sequence2.cxx:44)
==1919== by 0x401091: main_savitch_4::sequence::attach(double const&) (sequence2.cxx:95)
==1919== by 0x403232: test5() (sequence_exam2.cxx:538)
==1919== by 0x40414E: run_a_test(int, char const*, int (*)(), int) (sequence_exam2.cxx:744)
==1919== by 0x404321: main (sequence_exam2.cxx:775)
==1919== Address 0x5a1ae50 is 0 bytes after a block of size 240 alloc'd
==1919== at 0x4C2C037: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1919== by 0x400C33: main_savitch_4::sequence::sequence(unsigned long) (sequence2.cxx:17)
==1919== by 0x4030AC: test5() (sequence_exam2.cxx:520)
==1919== by 0x40414E: run_a_test(int, char const*, int (*)(), int) (sequence_exam2.cxx:744)
==1919== by 0x404321: main (sequence_exam2.cxx:775)
==1919==
我尝试使用 --leak-check=full 和 --read-var-info=yes 运行 valgrind,但无法确定我收到此错误的原因。调整大小的第 45 行是这样的:new_vals[i] = data[i];
谢谢!!!
【问题讨论】:
-
不要将
used设置为new_capacity。在此之前检查used是否大于new_capacity。另外,std::vector<double>不应该在这里就足够了吗? -
是的 std::vector
将是一个完美的工具,但这是我必须重新发明轮子的家庭作业。我更新了上面的代码,它现在检查 new_capacity -
那我想说用其他方法修改
used的代码可能有问题。 (另外,在将data设置为new_vals之前,您似乎忘记了delete[] data;o) -
我在将 new_vals 分配给数据之前添加了 delete [] 数据。我还包含了调用 resize 的函数的代码。仍然从 valgrind 得到同样的错误,虽然我肯定丢失了从 4320 字节到 2640 字节。
-
您是否可以将问题包含在SSCCE 中?如前所述,它是高度推测性的,因为我们既不知道它是如何使用的,也不知道所涉及的所有实现。但是,我确实对 resize 和 attach 中的变量管理有一些严重的怀疑。例如,为了您的对象的完整性和原始性,在您真正添加您的新值之前,不要修改“used”。同样适用于调整大小和容量成员。这使得两个成员非常难以分开管理。