简体   繁体   中英

Freeing memory allocated to an array of void pointers

I am declaring an array of void pointers. Each of which points to a value of arbitary type.
void **values; // Array of void pointers to each value of arbitary type

Initializing values as follows:


    values = (void**)calloc(3,sizeof(void*));
    //can initialize values as: values = new void* [3];
    int ival = 1;
    float fval = 2.0;
    char* str = "word";
    values[0] = (void*)new int(ival);
    values[1] = (void*)new float(fval);
    values[2] = (void*)str;

    //Trying to Clear the memory allocated
    free(*values); 
    //Error: *** glibc detected *** simpleSQL: free(): invalid pointer: 0x080611b4
    //Core dumped
    delete[] values*;
    //warning: deleting 'void*' is undefined
    //Similar Error.

Now how do I free/delete the memory allocated for values ( the array of void pointers)?

I suspect the issue is with the way that you allocated values : values = (void*)calloc(3,sizeof( )) . ))That should be sizeof(void *) rather than just sizeof(void) .

sizeof(void) may be zero or something else that makes no sense, so you're not really allocating any memory to begin with... it's just dumb luck that the assignments work, and then the error pops up when you try to deallocate the memory.

EDIT: You're also asking for trouble by alternating between C++-style new / delete with C-style malloc / free . It is okay to use them both as long as you don't delete something you malloc 'ed or free something you new 'ed, but you're going to mix them up in your head if you go like this.

You have 3 things that are dynamically allocated that need to be freed in 2 different ways:

delete reinterpret_cast<int*>( values[0]);    
delete reinterpret_cast<float*>( values[1]);

free( values); // I'm not sure why this would have failed in your example, 
               //    but it would have leaked the 2 items that you allocated 
               //    with new

Note that since str is not dynamically allocated it should not (actually cannot ) be freed.

A couple of notes:

  • I'm assuming that the sizeof(void) was meant to be sizeof(void*) since what you have won't compile
  • I'm not going to say anything about your seemingly random casting except that it looks like code that ready for disaster in general

This is the perfect situation for the boost::any class
Also you may want to consider using a vector rather than allocating your own memory.

std::vector<boost::any>   data;
boost::any i1 = 1; // add integer
data.push_back(i1);

boost::any f1 = 1.0; // add double
data.push_back(f1);

data.push_back("PLOP"); // add a char *

std:: cout << boost::any_cast<int>(data[0]) + boost::any_cast<double>(data[1])
           << std::endl;

Going back to your original code the main problem was:

values = (void*)calloc(3,sizeof(void));

// This should  have been
void** values = (void**)calloc(3,sizeof(void*));

// Freeing the members needs care as you need to cast them
// back to the correct type before you release the memory.

// now you can free the array with
free(values);

Also note: Though it is not illegal to use both new/delete and calloc/free in the same piece of code it is frowned upon. Mainly because it is easy to get things mixed up and that could potentially be fatal.

You're mixing new and *alloc(). That's a no-no, and can lead to undefined results.

You'd have to keep track of how many void* were originally calloc'd, and iterate over them, free-ing each one, then free the original values variable.

darn formatting... (the preview is working fine).

int ct = 3;
values = (void*)calloc(ct,sizeof(void));
//can initialize values as: values = new void* [3];
int ival = 1;
float fval = 2.0;
char* str = "word";
values[0] = (void*)new int(ival);
values[1] = (void*)new float(fval);
values[2] = (void*)str;

for ( int i = 0; i < ct; i++ ) [
    delete( values[i] );
}
free( values );

I'm not sure why you are using new if you're doing things in C (referencing the tag here).

I would malloc the individual pieces of the array I need and then free them when I'm done I suppose. You can't free something you didn't first malloc. You also can't delete a void pointer.

请注意,您也没有删除值[0]和值[1]这是一个内存泄漏,但是根据您的设计,您不能释放值[2],因为它是指向您.data部分的指针。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM