plz debug this! delete operator error

Started by
12 comments, last by Helter Skelter 18 years, 9 months ago
Hi I'm writing my own realloc function for my C++ objects. I've written a small prototype function to test it. I'm getting an error where it says "ERROR". Is there any other solution to this ? plz debug this. <code> #include <memory.h> #include <stdio.h> void* redim(void* source, int sourceSize, int targetSize) { fprintf(stderr, "target size: %d\n", targetSize); void* target = new char[targetSize]; fprintf(stderr, "target address: %x\n", target); if(source != NULL) memcpy(target, source, sourceSize); fprintf(stderr, "target address: %x\n", target); fprintf(stderr, "source address: %x\n", source); fprintf(stderr, "ready to crash!\n"); delete source; source = NULL; fprintf(stderr, "AFTER DELETE target address: %x\n", target); return target; } void main() { int *ptr; int *ptr1; // ptr = new (int); ptr = NULL; ptr = (int*)redim(ptr, 0,4); ptr = (int*)redim(ptr, 4,10); ptr = (int*)redim(ptr, 10,10); ptr = (int*)redim(ptr, 10,10); ptr = (int*)redim(ptr, 10,10); ptr = (int*)redim(ptr, 10,10); ptr1 = (int*)redim(ptr, 10,10); ptr1 = (int*)redim(ptr, 10,20); fprintf(stderr, "ERROR!\n"); ptr1 = (int*)redim(ptr, 20,30); ptr1 = (int*)redim(ptr, 30,40); } </code>
Advertisement
Quote:Original post by sriniatig
Hi
I'm writing my own realloc function for my C++ objects.


Then your asking for trouble really, you should never use C memory rountines directly on NON POD-types (Plain old data type), especially realloc it completely messes up C++ objects that are instances of NON POD-types.

Use the c++ standard library vector/deque for dynamic arrays they do automatically grow and do it as efficiently as possible. You can even provide custom allocator types to them.
we'll use vector/deque, but can you point why it is giving the error.
Quote:Original post by sriniatig
Hi
I'm writing my own realloc function for my C++ objects.


Why?

PS, 'code' tags go in square brackets; they are not HTML.

Hi.

You give NULL to ptr before first redim call, so the delete fail on NULL.

fprintf(stderr, "ready to crash!\n");
delete source;
source = NULL;

change to this:

fprintf(stderr, "ready to crash!\n");
if( source != NULL ) delete source;


This may will work.
BUG:	ptr1 = (int*)redim(ptr, 10,10);	ptr1 = (int*)redim(ptr, 10,20);	fprintf(stderr, "ERROR!\n");	ptr1 = (int*)redim(ptr, 20,30);	ptr1 = (int*)redim(ptr, 30,40);}



When you call redim() it releases the memory pointed to by 'ptr'. Since the pointer is no longer valid the next time you call redim() it's trying to release and access memory that is no longer available.

You also have a bug in redim(). Setting "source" to NULL only affects the variable in redim(). It has no affect on "ptr" or "ptr1" in main().

You are also mixing data types. Using "new char[50]" to allocate data that is intended to be accessed as an int array will eventually case you problems.

Also, memory allocated as an array should be released using "delete[]" instead of just plain "delete".


You really should go back and rethink your approach. You might want to consider finding someone that is proficient in C++ and has time to act as a mentor.
we tried this interesting thing with our code. I debugged the code to find out that the pointer is not becoming null in the redim function. So I made the function accept a double pointer and then executed it. It ran perfectly fine!
Here is the code...

<code>
#include <memory.h>
#include <stdio.h>

void* redim(void **source, int sourceSize, int targetSize)
{
fprintf(stderr, "target size: %d\n", targetSize);

void* target = new char[targetSize];

fprintf(stderr, "target address: %x\n", target);

if(*source != NULL)
memcpy(target, *source, sourceSize);

fprintf(stderr, "target address: %x\n", target);
fprintf(stderr, "source address: %x\n", source);

fprintf(stderr, "ready to crash!\n");

delete *source;
*source = NULL;

fprintf(stderr, "AFTER DELETE target address: %x\n", target);
return target;
}

void makeNull(void **ptr)
{
*ptr = NULL;
}

void main()
{
int *ptr;
int *ptr1;

int *ptr2;
ptr2 = (int *)new char[4];
*ptr2 = 10;

makeNull((void **)&ptr2);

ptr = NULL;
ptr = (int*)redim((void **)&ptr, 0,4);

ptr = (int*)redim((void **)&ptr, 4,10);

ptr1 = (int*)redim((void **)&ptr, 10,10);
ptr1 = (int*)redim((void **)&ptr, 10,20);

fprintf(stderr, "ERROR!\n");
ptr1 = (int*)redim((void **)&ptr, 20,30);
ptr1 = (int*)redim((void **)&ptr, 30,40);
}

</code>
Quote:Original post by cuBie
You give NULL to ptr before first redim call, so the delete fail on NULL.

if( source != NULL ) delete source;


This may will work.


[rolleyes] it is permitted to pass null pointers to operators delete/delete[].

Quote:Original post by sriniatig
It ran perfectly fine!


Now try that code on a dynamic array of a NON POD-type (which typically most C++ user-defined types are) and see what happens.

Also listen to what Helter Skelter told you, your mixing the wrong operators new/delete.

In any case you should be using vector/deque for dynamic arrays in C++.
delete call will not crash even if the pointer is NULL. and on the delete function calling mistake ( we shoul have used delete [] ptr) will still not solve the problem. We understood the referencing problem and so we used double pointers.
Quote:Original post by sriniatig
delete call will not crash even if the pointer is NULL.


As already mentioned previously.

Quote:Original post by sriniatig
We understood the referencing problem and so we used double pointers.


Now understand that the code is not only naive its not going to work correctly for certain C++ objects in particular NON POD types.

This topic is closed to new replies.

Advertisement