All malloc does is allocating x bytes of memory. What it doesn't do is actually creating an instance of a particular type. The fact that you have to cast the result to appropriate pointer is a huge give-away.
Therefore it cannot be used for creating objects whose constructor actually does something. In case of your struct the compiler-generated constructor does something, and namely, it calls the default constructor for the string member.
If you want to use malloc, you'll also need to create the object in the returned memory, and this can be done with placement new:
Code:
a *create()
{
void* p = malloc(sizeof(a));
a* pa = new (p) A;
pa->count=0;
pa->k="XX";
return a;
}
Because the compiler-generated destructor also does something, namely call the destructor of the string member which releases the memory allocated by the string object, you must also remember to call the destructor before freeing the pointer.
Code:
int main()
{
a* test = create();
//...
test->~a();
free(test);
return 0;
}
Those steps are combined in new and delete.
In addition new also handles errors, so as not to leak memory if constructing the object throws an exception, performing something analogous to this:
Code:
void* p = malloc(sizeof(a));
try {
return new (p) a;
}
catch (...) {
free(p);
throw;
}
In short, new is what one uses for allocating anything other than plain-old-data types.