To: ryoung AT clark DOT dgim DOT doc DOT ca (Richard Young) Cc: djgpp AT sun DOT soe DOT clarkson DOT edu Subject: Re: Complex new/delete bug Organization: Code Generation Technology, San Francisco, CA Date: Tue, 04 Jan 94 14:55:12 -0800 From: "Thomas J. Merritt" |<><><><><> Original message from ryoung AT clark DOT dgim DOT doc DOT ca <><><><><> |I have found a bug when creating complex arrays with new and then deleting |them. The deletion of the complex array does not seem to free up the memory |that was allocated and a succession of new/delete will eventually result in |an insufficient memory error. The bug is in your code. |I have been able to circumvent the bug by refraining from using new complex[n]. |In place of | complex * x = new complex[n]; |I use | complex * x = (complex *)malloc(n*sizeof(complex)); This is just masking the bug. |The following test program, which I named testmemf.cc, illustrates the problem. | I have listed the various tests that I ran below: |> testmemf 1 using new complex[n], will eat up memory and die, note new'ed | ptr increasing Yup. |> testmemf 2 no problem with double arrays, ptr not increasing Not suprising. |> testmemf 3 no problem with single complex objects, ptr not increasing Yup. |> testmemf 4 no problem with malloc(n*sizeof(complex)) instead of new | complex(n) Not suprising. |> testmemf 5 seems to show that the amount of memory allocated with new is | OK, that is, the delta between ptrs is n*sizeof(complex) bytes Strange. There should be a little bit of overhead for malloc. |> testmemf 6 same delta as test 5 but I found it odd when the address of | the 1st ptr here was consistently different than in test 5 Not suprising. |Although I am avoiding the problem for now I would appreciate if someone could |locate and |fix the bug. | |Thanks and Merry Christmas!!! | |Richard Young, DSP engineer |Communications Research Centre |3701 Carling Ave., |Ottawa, Ontario |Canada |K2H 8S2 |(tel) (613)998-2235 |(fax) (613)990-6339 |(e-mail) richard DOT young AT crc DOT doc DOT ca | |//-------------------- testmemf.cc ------------------------------------------ |-------------- | |#include |#include |#include | |int main (int argc, char *argv[]) |{ | if (argv[1][0] == '1') // successive new/delete with complex arrays | { | for (;1;) | { | complex * x = new complex[1000]; | printf("%c x=%p\n",argv[1][0],x); | delete x; Need to do a 'delete[] x;' | } | } | else if (argv[1][0] == '2') // successive new/delete with double arrays | { | for (;1;) | { | double * x = new double[1000]; | printf("%c x=%p\n",argv[1][0],x); | delete x; Still need to do a 'delete[] x;' | } | } | else if (argv[1][0] == '3') // successive new/delete with single complex ob |jects | { | for (;1;) | { | complex * x = new complex; | printf("%c x=%p\n",argv[1][0],x); | delete x; This is OK. | } | } | if (argv[1][0] == '4') // successive new/delete with malloc'ed complex | array store | { | for (;1;) | { | complex * x = (complex *)malloc(sizeof(complex[1000])); | printf("%c x=%p\n",argv[1][0],x); | delete x; This is undefined behaviour. You can't mix malloc/free with new/delete. | } | } | if (argv[1][0] == '5') // to check amount of memory allocated to each |new array | { // using new | complex * x = new complex[1000]; | complex * y = new complex[1000]; | complex * z = new complex[1000]; | printf("%c x=%p y=%p z=%p\n",argv[1][0],x,y,z); | } | if (argv[1][0] == '6') // to check amount of memory allocated to each |new array | { // using malloc | complex * x = (complex *)malloc(sizeof(complex[1000])); | complex * y = (complex *)malloc(sizeof(complex[1000])); | complex * z = (complex *)malloc(sizeof(complex[1000])); | printf("%c x=%p y=%p z=%p\n",argv[1][0],x,y,z); This may take slightly less memory since C++ arrays are prefixed with a length count. | } | return 0; |} | |//-------------------- end of testmemf.cc ----------------------------------- |--------------- TJ Merritt tjm AT netcom DOT com