开发者

How can a delete[] operation crash while the destructor succeeds? (in C++)

开发者 https://www.devze.com 2023-03-31 15:13 出处:网络
I have a class Foo, which has a (simple) destructor. Some other class contains an array of Foo objects (called foolist), in the destructor of that class, I do:

I have a class Foo, which has a (simple) destructor.

Some other class contains an array of Foo objects (called foolist), in the destructor of that class, I do:

delete[] foolist;

This crashes (gdb shows that it crashes in this exact line). However, by using printouts I 开发者_如何学Pythonsee that all the elements in foolist are finishing their destructor without problems (the number of destructors that runned is also equal to the number of objects allocated in this array, so they all get destructed). There is also no other delete for foolist in the code.

I also made sure that foolist is indeed initialized as an array, in this way:

foolist = new Foo[number];

The error is:

*** glibc detected *** /home/bas/projects/trunk/main:
free(): invalid next size (fast): 0x080a0e80 ***

What could cause delete[] to crash in this case?

Thanks in advance!

As asked also the output of valgind here (statementNode is Foo, and programNode the class containing list of Foo's)

==4111== 1 errors in context 1 of 2:
==4111== Invalid write of size 4
==4111==    at 0x804B6FA: Parser::parseProgram(std::string) (statementnode.h:35)
==4111==    by 0x80764D4: main (parser.h:35)
==4111==  Address 0x42d9bdc is 4 bytes after a block of size 32 alloc'd
==4111==    at 0x4025F53: operator new[](unsigned int) (vg_replace_malloc.c:299)
==4111==    by 0x804A81E: Parser::parseProgram(std::string) (programnode.h:21)
==4111==    by 0x80764D4: main (parser.h:35)

StatementNode:35 is the creation of a completly different object. ProgramNode:21 is the creation of foolist / list of StatementNodes.. Hope this helps.


The delete operator performs 2 functions under the hood

  1. Run Destructors
  2. Free Memory

Given the printout confirms #1 is happening the most likely cause is a crash during the actual freeing of memory (the message indicates this as well). This typically indicates that the memory is being corrupted by another part of your program.

Have you tried running your program under valgrind?


Looks like our good old pal "undefined behaviour".

Maybe foolist is deleted twice. Have you overloaded the class' copy constructor and assignment operator? If not, you should read this: What is The Rule of Three?


You could have double deleted it- even unintentionally by violating the Rule of Three. You could have changed the value of the pointer- e.g. incrementing it. You could have polymorphically converted it, e.g. Base* ptr = new Derived[size]; delete[] ptr; which is also undefined behaviour.

Lesson: Always, always, always use a smart pointer.

0

精彩评论

暂无评论...
验证码 换一张
取 消