0

I am implementing a stack and I would like to push and pop string data. can I not just set

string name = originalString ???

here is what I have for push:

void push(StackNode** top_ref, int nAttack, int nDefense, string nName, string nType) {
    StackNode* stackNode = (StackNode*)malloc(sizeof(StackNode));
    stackNode->attack = nAttack;
    stackNode->defense = nDefense;

    stackNode->name = nName; //not working
    stackNode->type = nType; //not working

    stackNode->next = NULL;
    stackNode->next = *top_ref;
    *top_ref = stackNode;
} 

where stackNode->name

and stackNode->type is already defind as a string

I keep getting: "Error reading characters of string."

  • Is this for an academic class where you're required to use `malloc`? If not, can I introduce you to `new[]`? And then after you've gotten accustomed to that, can I introduce you to `std::stack`? https://en.cppreference.com/w/cpp/container/stack – JohnFilleau Mar 18 '20 at 03:08
  • Can you show the `StackNode` class please? – JohnFilleau Mar 18 '20 at 03:11
  • Yepp new made it work, although I am not quite sure why it is so different to malloc. Thanks for the help! I replaced malloc with this for future people StackNode* stackNode = new StackNode; – conglomerate Mar 18 '20 at 03:20
  • `malloc` is dumb and only gives you that amount of memory. The constructor isn't called. With `new`, the constructor is called. That's the difference. – JohnFilleau Mar 18 '20 at 03:20
  • But to be clear - this is for an academic exercise where you're required to do your own memory management? Because the C++ best practice is to use STL containers when they're appropriate. Here, you'd use `std::stack`. – JohnFilleau Mar 18 '20 at 03:21

1 Answers1

0

The issue is malloc doesn't play well with objects. See Does malloc create a new instance of the class or not?

malloc allocates enough space to hold a StackNode, but doesn't call the constructor on it. Nor does it create the underlying member objects, your strings included. To do so, you need to do like described in this answer:

A* a = (A*)malloc(sizeof(A));
new (a) A();

a->~A();
free(a);

But at this point, you really should just be using new anyway. There's very little reason to use new in C++ (there's a time and a place, but minimize it). There's even fewer times when it's right to call malloc.

Do

StackNode* stackNode = new StackNode;

which will call the constructor appropriately. Remember to call delete on the memory when you're done with it!

JohnFilleau
  • 4,045
  • 1
  • 15
  • 22