I am trying to dynamically allocate an array of struct in another struct here is the code segment
I don't get any syntax errors but I get segmentation fault once I try to enter str1
could someone explain why is there a segmentation fault, and what happens in memory in the dynamic allocation in such situation
struct A {
string str1;
string str2;
}
struct B {
int count;
A* A_array;
}
void GetB (B** b)
{
*b = (B*) malloc(1*sizeof(B));
cout << "Enter count";
cin >> (**b).count;
(**b).A_array = (A*) malloc((**b).count*sizeof(A));
cout << "Enter str1";
cin >> (**b).A_array[0].str1;
cout << "Enter str2";
cin >> (**b).A_array[0].str2;
}
int main(){
B* b;
GetB(&b);
}
2 Answers 2
The reason you are getting a crash is because string str1; string str2; do not get constructed properly.
And they are not constructed properly because malloc only allocates memory and doesn't call the constructors.
Which is what operator new is for in C++.
Therefore, as highlighted in comments:
- Never ever use
mallocto allocate non-POD objects. - Even better, never use
mallocin c++ at all. - And better still, never ever use manually allocated arrays, use
std::vectorinstead
5 Comments
malloc with new in both lines and it workedmallocs to news is only a quick and dirty fix for your code and that there are more and larger issues to it? You'll make it a lot easier for your future self if you learn now how to do things the C++ way instead of continuing with your current style until you hit a project complex enough where it fails.B still has signature void GetB (B** b) when it could simply be B GetB() avoiding the pointers entirely. You are still using A* instead of vector<A>. You may want to explore whether your classes should have constructors, or whether their members should be private.Expanding on my comments, this would be an equivalent of your current program using some more idiomatic C++. I have deliberately kept the structure as close to your original as possible, but there are of course other issues to think about, like whether your classes should have constructors or private members.
struct A {
string str1;
string str2;
};
struct B {
int count;
vector<A> A_vec;
};
B GetB ()
{
B myB;
cout << "Enter count";
cin >> myB.count;
A a;
cout << "Enter str1";
cin >> a.str1;
cout << "Enter str2";
cin >> a.str2;
myB.A_vec.push_back(a);
return myB;
}
int main(){
B b(GetB());
}
mallocinstead ofnew? Generally, if you're programming in C++, you want to actually use C++.cinorcoutand don't cast the return frommalloc. If you're writing C++, don't usemallocat all, and usestd::vectorinstead of your home-rolled imitation.