C ++为什么new关键字有效而malloc无效?

问题描述

我正在学习有关指针和结构的信息,遇到这种难以理解的问题。 我已经创建了这个简单的程序用于测试:

#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;
}

上面的程序工作得很好,它显示值400。但是当我尝试使用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;
}

它给了我这个价值: -842150451

为什么? 以上示例是在Visual Studio 2019中编写并构建的。

我知道在C ++中,您几乎总是应该使用new关键字,但我想尝试一下。

解决方法

new使用类的构造函数初始化分配的内存(在这种情况下是隐式的)。

malloc不执行初始化,它只分配一部分内存。读取未初始化的内存将具有未定义的行为。

,

这是使第二个示例生效的方式。通常,这不是推荐的使用C ++的方法,但是有一些有效的用例。

#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);
}
,

对于malloc,您分配了一块内存,但是没有创建对象。 testStructure构造函数未被调用。

您可以使用新的放置位置在内存区域调用构造函数:

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

但这很难读,容易混淆,难以维护并且充满风险。例如,您需要

  • 要free()不能删除ptr
  • 您需要类似地显式调用析构函数。

所以,不推荐。