无法删除临时对象
Can't delete temporary object
我正在调整对象数组的大小。我做了一个临时对象,但当我不删除它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,但是得到了这个backtrace:
(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
而不是手工制作的数组,为我照顾释放
如果这是第二次(或更晚)调用resize
,那么很可能出现这种情况,因为您正在尝试在已经有double delete
的堆上执行delete
,因为temp
已经删除,现在所有objArray
写入都进入了属于堆管理的一块内存,而不是属于您的代码。
所有其他潜在的问题也可能发生在这里,比如内存现在被用于一些其他对象,并且它正在将东西写入堆内存,然后用作objArray。
你不应该删除temp
,当你试图这样做。只是不喜欢。
明确的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[]>
)都留下了一个有效的缓冲区。
- 在不复制临时对象的情况下延长其生存期
- 为什么当我们有常量引用时创建临时对象?
- 程序如何'remember'临时对象?
- 返回对临时对象的引用
- 线程调用的函数对对象删除是否安全?
- 防止临时对象文件访问 MSVC 中的磁盘
- 是否可以在C++中移动临时对象的属性?
- 通过引用传递临时对象
- 临时C++对象是否为左值?
- 临时对象:术语澄清
- 存储对(可能)临时对象的引用是否合法,只要引用不比对象存活?
- 临时对象有身份吗?
- 临时对象上的运算符重载
- 如何在没有 std::move 的情况下移动临时对象
- 临时对象在C++中是不可避免的吗?
- 编译错误:临时对象构造函数中缺少参数
- 为什么在按值返回时创建临时对象,而不是在按值传递给函数参数时创建临时对象
- 如何避免在使用初始值设定项列表构造时创建(和删除)临时对象
- 如果没有对临时对象的常量引用,它会被删除吗
- 无法删除临时对象