无法删除临时对象
我正在调整大小和对象数组。我做了一个临时对象,但是当我不删除它时,Valgrind显示内存泄漏和错误。删除它会导致段错误。只是不知道什么Valgrind的抱怨......无法删除临时对象
void Obj::resize()
{
Obj *temp = new Obj[size * 2]; //<-- line 92
for (int i = 0; i < size; i++)
temp[i] = objarray[i];
delete [] objarray;
objarray = temp;
size *= 2;
//delete temp; //<-- causes segfault
//delete [] temp; // also segfaults, tried them both just in case :\
}
这里的Valgrind的报告:
==9292== HEAP SUMMARY:
==9292== in use at exit: 21,484 bytes in 799 blocks
==9292== total heap usage: 3,528 allocs, 2,729 frees, 91,789 bytes allocated
==9292==
==9292== 21,484 (2,644 direct, 18,840 indirect) bytes in 1 blocks are definitely lost in loss record 4 of 4
==9292== at 0x4008409: operator new[](unsigned int) (vg_replace_malloc.c:357)
==9292== by 0x804AC7E: MyClass::resize() (file.cpp:92)
==9292== by 0x804AC34: MyClass::add(int, int) (file.cpp:82)
==9292== by 0x804AAE6: getline(std::istream&, MyClass&) (file.cpp:66)
==9292== by 0x8049772: main (otherfile.cpp:39)
==9292==
==9292== LEAK SUMMARY:
==9292== definitely lost: 2,644 bytes in 1 blocks
==9292== indirectly lost: 18,840 bytes in 798 blocks
==9292== possibly lost: 0 bytes in 0 blocks
==9292== still reachable: 0 bytes in 0 blocks
==9292== suppressed: 0 bytes in 0 blocks
==9292==
==9292== For counts of detected and suppressed errors, rerun with: -v
==9292== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
我不是用gdb太好,但得到这个回溯:
(gdb) run
Starting program:
Program received signal SIGSEGV, Segmentation fault.
0x46ed40e3 in free() from /lib/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.15-58.fc17.i686 libgcc-4.7.2-2.fc17.i686 libstdc++-4.7.2-2.fc17.i686
(gdb) backtrace
#0 0x46ed40e3 in free() from /lib/libc.so.6
#1 0x4742dba0 in operator delete(void*)() from /lib/libstdc++.so.6
#2 0x0804ad68 in MyClass::resize (this=0xbffff28c) at file.cpp:98
#3 0x0804ac35 in MyClass::add (this=0xbffff28c, month=10, day=31)
at file.cpp:82
#4 0x0804aae7 in getline (input=..., a=...) at file.cpp:66
#5 0x08049773 in main (argc=1, argv=0xbffff344) at otherfile.cpp:39
(gdb)
我认为删除它是不好的,因为它应该让指针悬空,所以我不会感到惊讶的是我得到了段错误。但是,为什么会造成内存问题呢?任何想法将不胜感激。
事实上,你可以不在那里删除它,因为你已经将其分配给objarray
供以后使用。
最有可能的,你没有删除在析构函数objarray
;或者其他一些函数重新分配它而不先删除旧数组。
我会用std::vector
而非手工制作的阵列,照顾释放的我。
谢谢。正如你(和其他人)所建议的那样,我忽略正确使用析构函数。 – mcallinder 2013-05-14 02:17:58
明确delete
(或delete[]
)应该只需要非常低级别的库代码。其他地方你应该使用智能指针。
这里有一个更好的方法是(IMO)更容易理解:
std::unique_ptr<Obj[]> temp(new Obj[size * 2]);
// copy stuff from objarray to temp
swap(objarray, temp);
就是这样。如果交换成功,则unique_ptr
析构函数将释放旧的objarray
缓冲区。如果在复制过程中抛出异常,它将释放新的临时缓冲区。在任何一种情况下,objarray
(也应该是std::unique_ptr<Obj[]>
)都留有一个有效的缓冲区。
使用'std :: unique_ptr'可能是最简单的解决方案,但我不认为'交换“将起作用; “swap”的两个参数必须具有相同的类型。 (当然,一般情况下,他基本上是重新实现了'std :: vector',并且在一般情况下正确执行了这个操作 - 例如,如果'Obj'不支持默认构造,那么这就不重要了。) – 2013-05-13 17:16:10
@James:自然'objarray'也应该是'unique_ptr
@Sarien:它只是交换指针。因此,现在'temp'拥有需要销毁的旧缓冲区,并且当它在'resize'的大括号处超出范围时就会这样做。 – 2013-05-13 17:19:01
如果这是第二次(或更高版本),你叫resize
时间,那么这是一个非常可能的情况,因为你正在试图delete
上已经产生了double delete
因为temp
已经删除了一堆,现在你所有的objArray
写入已经进入了一堆属于堆管理的内存,而不是你的代码。
各种其他潜在的问题也可能发生在这里,例如内存现在被用于一些OTHER对象,并且它将事物写入堆内存中,然后将其用作objArray。
,你正在尝试做的,所以你不应该删除temp
。不要。
为什么你会删除'temp'? **你不应该**。删除不释放指针,但指向它。如果你删除'temp',你也会删除你的'objarray'(*它指向*)。 – stardust 2013-05-13 17:05:27
是的,我意识到这一点。我想知道的是为什么它仍然会造成内存问题? – mcallinder 2013-05-13 17:07:48
段错误可能是由其他内容引起的。你会在那里看到效果。但原因可能是在... – stardust 2013-05-13 17:09:21