Reputation: 4403
I have a very simple piece of code with 2 structures and one dynamic allocation. The program crashes on the "nume" initialization.
typedef struct{
int key;
string name;
} TElement;
typedef struct nod {
int cheie;
string nume;
struct nod *stg, *dr;
} NOD;
when i try to do this
void ABC::inserare_element(TElement e){
NOD *p, *q;
int n;
/* construction nod p*/
n=sizeof (NOD);
p=(NOD*)malloc(n);
p->cheie = e.key;
p->nume = e.name; // on this line the program crashes
Thanks
Upvotes: 2
Views: 256
Reputation: 122001
malloc()
will not invoke the constructor of NOD
, meaning the constructor of nume
will not have been invoked resulting in an attempt to use std::string::operator=
on an unconstructed/uninitialized std::string
: use new
.
Upvotes: 7
Reputation:
You have a hot mix here of high-level C++ objects, such as std::string
and C-style memory allocations such as malloc
. The thing is that C++'s new
operator not only allocates memory, but also calls constructor of high-level objects. The problem you are facing is that nume
object of type std::string
is not initialized properly, thus you run into undefined behavior that leads to a crash. That is because you are lucky. It could have been a lot worse if program was actually working, but producing strange, unexpected results.
To make it work like you want, you can simply use new
instead of malloc
. For example:
p = new NOD;
If it so happens that you really need to use malloc
or other memory management API that does not care about C++ objects, then you have to call a constructor of nume
manually, using a placement new. For example:
p = (NOD*)malloc(n);
new ((void *)&p->nume) std::string();
In case you go that way - don't forget to call destructor as well or you will end up with a memory leak.
Upvotes: 4
Reputation: 701
You should use new instead of malloc. malloc is a C function and it only allocates a chunk of memory. Using new will call the default constructor of your class, and the string constructor will also be called at this moment.
Upvotes: 3