GreenVoice
GreenVoice

Reputation: 23

C++ why does new keyword works and malloc does not?

I'm learning about pointers and structures and I ran into this hard to understand the problem for me. I have created this simple program for testing purpose:

#include <iostream>

struct testStructure
{
    int a = 0;
    int b = 0;
    int c = 400;
};

int main()
{
    struct testStructure* testStruct;
    testStruct = new testSctructure;

    std::cout << testStruct->c;

    delete testStruct;
    return 0;
}

the above program works just fine, it prints the value 400. But when i try to do it with malloc:

#include <iostream>

struct testStructure
{
    int a = 0;
    int b = 0;
    int c = 400;
};

int main()
{
    struct testStructure* testStruct;
    testStruct = (testStructure*)malloc(sizeof testStructure);

    std::cout << testStruct->c;

    free(testStruct);
    return 0;
}

it gives me this value: -842150451

Why? The above examples were written and build in Visual Studio 2019.

I know that in C++ you should almost always want to use new keyword but I wanted to experiment a bit.

Upvotes: 1

Views: 76

Answers (3)

Jeffrey
Jeffrey

Reputation: 11400

In the case of malloc, you allocated a block of memory, but did not create an object. The testStructure constructor was not called.

You could call the constructor on the memory area with a placement new:

char* ptr = malloc(sizeof testStructure);
testStruct = new(ptr) testStructure;

but this is hard to read, confusing, hard to maintain, and fraught with risk. For example, you need

  • to free() not delete ptr
  • you need to similarly explicitly call the destructor.

So, not recommended.

Upvotes: 2

Eljay
Eljay

Reputation: 5321

Here's how your second example can be made to work. In general, this is not a recommended way of working with C++, but there are some valid use cases.

#include <cstdlib>
#include <iostream>

struct testStructure {
    int a = 0;
    int b = 0;
    int c = 400;
};

int main() {
    auto testStruct_memory = std::malloc(sizeof(testStructure));

    // In-place constructor.
    auto testStruct = new(testStruct_memory) testStructure();

    std::cout << testStruct->c << "\n";

    // In-place destructor.
    testStruct->~testStructure();

    std::free(testStruct_memory);
}

Upvotes: 2

Mureinik
Mureinik

Reputation: 311188

new initializes the allocated memory with the class' constructor (which is implicit in this this case).

malloc performs no initialization, it just allocates a portion of memory. Reading uninitiazlied memory will have undefined behavior.

Upvotes: 3

Related Questions