-2
struct A
{
 string st;
};

int main()
{
 A *a = (A *)malloc(sizeof(A));
 a->st = "print";

 cout << a->st;
 return 0;
}

When I use this way and it compiled successfully, but after that in runtime I got exception. So, I figure out one thing is A *a = new A; instead of A *a = (A *)malloc(sizeof(A));. Which way is better and without error for doing this type of things?

What should I do for runtime memory allocation?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • 2
    You ***must*** use `new` in c++, otherwise your code has undefined behavior. – πάντα ῥεῖ Aug 24 '22 at 11:31
  • 1
    `malloc` does not invoke the constructor, only allocates memory. So your object is uninitialized and accessing it is UB. You should avoid `malloc` in c++ and use `new`, or even better as mentioned above - do not use dynamic allocation at all if possible. – wohlstad Aug 24 '22 at 11:31
  • 1
    Generally, you can use `malloc` instead of the [`new` _operator_](https://en.cppreference.com/w/cpp/memory/new/operator_new); however, you cannot use `malloc` instead of the [`new` _expression_](https://en.cppreference.com/w/cpp/language/new). – Daniel Langr Aug 24 '22 at 11:42
  • 1
    Can you share which C++ textbook discussed using `malloc` in C++ code? No, no C++ textbook does that. This kind of question only comes up as a result of attempting to use Google as a replacement for a good C++ textbook. Unfortunately, Google is not a replacement for a C++ textbook. – Sam Varshavchik Aug 24 '22 at 11:49
  • Curios - does this always throw a runtime error? I'm thinking it should, in theory but I got it running in an online compiler (if I added `#include ` and `using namespace std;` at the top) without errors and it did output "print". (Specifically https://www.onlinegdb.com/online_c++_compiler) – Drkawashima Sep 04 '22 at 18:25
  • I can see why this question was asked. The code is very close to the first example code in https://www.geeksforgeeks.org/arrow-operator-in-c-c-with-examples/ except for the line that initially creates the object and sets it to NULL – Drkawashima Sep 04 '22 at 18:30

1 Answers1

5

malloc alone is outright wrong. malloc allocates memory, it does not create objects.

new allocates memory and creates an object by calling the constructor.

The "better" way is to not use either of the two when there is no reason to use them.

int main() {
   A a;
   a.st = "print";
   cout << a.st;
}

A has only a single member of type std::string. std::string is already managing a dynamically allocated character string. There is no reason to dynamically allocate a std::string, and also no reason to use new to create an A.

If you still need to dynamically allocate an object you should not use raw owning pointers. Your code leaks memory and there is no trivial fix for that (a delete at the end of main may never be reached when an exception is thrown). Use smart pointers when you do need to dynamically allocate an object.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • Malloc isn’t totally wrong, but you do have to construct your objects (with some exceptions in C++20), and you have to destruct the objects (not strictly true but yikes) and `free` the `malloc`ed memory. So just use `new` and `delete`. Or better: use `std::make_unique`. – Ben Aug 24 '22 at 11:54