A: 

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 );
Bill James
crap... please, someone tell me how to format a block to look like code.
Bill James
put 4 spaces before each line
fizzer
And don't use the pre tag.
Martin York
Seriously, just don't do anything and it'll format code.... awesome. Thanks for the help
Bill James
A: 

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.

Jon
+7  A: 

I suspect the issue is with the way that you allocated values: values = (void*)calloc(3,sizeof(void)). 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.

Dan
Good catch on the void * vs. void thing. I didn't notice that.
Jon
Thanks! sizeof(void) really set the alarm bells off in my head :-)
Dan
+5  A: 

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
Michael Burr
I gotta agree with Mike on the "disaster" part. To the OP: are you trying to program in C, or C++? In C, casts to void* often make sense, but you've got to know what you're doing. In C++, there are other idioms for what you seem to be doing. Decide what language you're trying to program in :)
Dan
I don't know how else to create a container holding data of different data types in c++. Tried using vectors, but u can only have data of the same type in it. Can anyone suggest some other way to do the above?
There are a variety of different ways to make containers for heterogeneous types. See thiS FAQ for a couple ways to do it in C++: http://www.parashift.com/c++-faq-lite/containers.html#faq-34.4
Dan
"I don't know how else to create a container holding data of different data types in c++" - that would be a great SO question itself. I think there might be some interesting answers that go beyond (or at least into more detail) over the C++ FAQ answer.
Michael Burr
My favorite answer is "use a dynamic language (like Perl, Python, Ruby) instead of C or C++". Seriously, by the time you've created a decent infrastructure to memory-manage and introspect arbitrarily-typed arrays, you've practically recreated one of those languages. :)
Dan
Please: Do what Martin York says. Don't continue down this path.
Matt Cruikshank
+1  A: 

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

Paul Nathan
Only if you are not careful (admittedly very careful). mixing malloc/delete is the problem here.
Martin York
A: 

Note that you're also not deleting values[0] and values[1] which is a memory leak, Yet by your design you can't free values[2] since its a pointer into you .data section.

Jeff Mc
A: 

I don't know how else to create a container holding data of different data types in c++. Tried using vectors, but u can only have data of the same type in it. Can anyone suggest some other way to do the above?

Boost::any. See my answer (probably below)
Martin York
+4  A: 

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.

Martin York
Now that is just awesome. I've seen so many good things about Boost, it might convince me to take up C++ again.
Dan