Skip to main content
gamedev.net
🔒 Locked

using new multiple times

Started by Lode Aug 9, 2005 at 5:26 AM 8 replies 900+ views
Original Post
Lode
Lode
I have in my code a function like this:

void bla(unsigned char* &buffer, int len)
{
    buffer = new buffer[len * 2];

    //fill buffer with stuff and do calculations and stuff
}
and in main, I do this (just a dumb example here):

int a = 0;
unsigned char* b;
bla(b, 10);
a += b[5];
bla(b, 11);
a += b[5];
delete[] b;
So basicly, because I called the bla function two times in main, it has been "new"-ed 2 times. Is that OK or can it give a memory leak? And it a good programming practice to use this system with a reference to a pointer?
DaBono
DaBono
Nope, sorry.. This leaks memory.
What you could do is ensure that a pointer is initialised with NULL, so you can do:
// if( pointer != NULL )    delete[] pointer;pointer = new char[size];

EDIT: Oops, busted.. Thanks, snk_kid, for pointing out the obvious mistake(s).

[Edited by - DaBono on August 9, 2005 6:29:32 AM]
snk_kid
snk_kid
Quote:
Original post by DaBono
Nope, sorry.. This leaks memory.
What you could do is ensure that a pointer is initialised with NULL, so you can do:
if( pointer != NULL )    delete pointer;pointer = new char[size];


Yes it does leak memory but checking for null before invoking operator delete/delete[] is redundant as a pointer is permitted to be null. Also your using the non array version of delete tisk, tisk.

@Lode: Unless you have a very good reason (i can assert you don't) use std::vector instead of C-style dynamic arrays.
Lode
Lode
Quote:
Original post by DaBono
Nope, sorry.. This leaks memory.
What you could do is ensure that a pointer is initialised with NULL, so you can do:
if( pointer != NULL )    delete pointer;pointer = new char[size];


It's not really working :(

I try this:

    int* b;    b = new int[500];    if(b != NULL) delete b;    if(b != NULL) delete b;


And it gives me the following output:

Quote:

*** glibc detected *** double free or corruption (top): 0x0804e008 ***
Aborted


How can I detect when deleting is permitted?

And a question: what's the difference between delete and delete[]?
snk_kid
snk_kid
Quote:
Original post by Lode
And a question: what's the difference between delete and delete[]?


The difference is you when you use new[] use delete[] using delete instead is a common bad mistake, please read my last message.
Lode
Lode
Allright, how would this work with std::vectors.

The bla function is one that loads a png image. Before you call the function to load a png, you don't know the size of the png yet, so you can't create the array yourself, it has to happen inside the function.

What is a safe way to create enough memory with a std::vector inside this function, and do you have to do anything special or different with it outside the function, or to do something like free or delete?

Are std::vectors really used to contain images?
MaulingMonkey
MaulingMonkey
Quote:
Original post by Lode
Quote:
Original post by DaBono
Nope, sorry.. This leaks memory.
What you could do is ensure that a pointer is initialised with NULL, so you can do:
if( pointer != NULL )    delete pointer;pointer = new char[size];


It's not really working :(

I try this:

    int* b;    b = new int[500];    if(b != NULL) delete b;    if(b != NULL) delete b;


And it gives me the following output:

Quote:

*** glibc detected *** double free or corruption (top): 0x0804e008 ***
Aborted


How can I detect when deleting is permitted?


You can't, very well. The "if(b != NULL) delete b;" relies on the user NULLing out b whenever he deletes it (unless it is immediately set to a new area of allocated memory).

If you're using C++, a better option may be std::vector - it "owns" the integers associated with it which means it will automatically delete them when it goes out of scope.

The original example would become:

#include <vector>void bla( std::vector< unsigned char > &buffer, int len){    buffer.clear(); //assuming you don't want the old data still there... if you're going to assign every element, you don't really need this since the old data will be overwritten anyways.    buffer.resize( len * 2 );    for ( int i = 0 ; i < buffer.size() ; ++i ) {        buffer[ i ] = i; //example fill    }}int main () {    int a = 0;    std::vector< unsigned char > b;    bla(b, 10);    a += b[5];    bla(b, 11);    a += b[5];    //no delete[] statement - when b goes out of scope it will automatically destroy the unsigned characters it "owns".}


Quote:
And a question: what's the difference between delete and delete[]?


malloc must be released with free,
new must be released with delete,
new[] must be released with delete[].

the plain "new" will allways be of a fixed size, so some optimizations can occur there, ditto with delete.

"new[]" must also track the number of elements allocated, and "delete[]" look up and free that same number.

(new[] = statements like "new unsigned char [ size ]").
HAM
HAM
Quote:
Original post by Lode


How can I detect when deleting is permitted?




You'l have to make that mechanism yourself.

If you are using null to test then after deleteing you need to set th pointer to null:

if (p!=NULL)
{
delete p;
p=NULL;
}

If you don't set the pointer to null then it is still pointing to the same memory.



Lode
Lode
Can you safely clear() std::vectors multiple times?

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.