You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C++的new关键字替代C的malloc?含void*内存分配问题

C代码转C++:解决栈实现中void*成员的内存分配问题

错误原因

你写new data_stack->objsize报错是因为C++的new关键字要求必须指定类型,不能直接传入字节大小——这和malloc的逻辑完全不同:malloc是按字节数分配原始内存,而new本质是创建指定类型的对象(或对象数组)。

两种正确替代方案

针对你需要分配data_stack->objsize字节原始内存的场景,有两种等价于malloc的写法:

方案1:用new char[]分配字节数组

因为char类型的大小是1字节,所以分配data_stack->objsize个char就等价于分配对应字节数的内存,之后可以直接转成void*:

nodeObject->obj = new char[data_stack->objsize];

注意:释放这块内存时必须用delete[],不能用普通delete:

delete[] static_cast<char*>(nodeObject->obj);

方案2:直接调用operator new全局分配函数

operator new是C++底层的内存分配函数,和malloc行为完全一致——只分配原始内存,不调用任何构造函数,返回void*:

nodeObject->obj = operator new(data_stack->objsize);

释放时对应调用operator delete,等价于free:

operator delete(nodeObject->obj);

完整C++改写代码

把原C代码全部替换为C++风格的写法(包括用new替代结构体的malloc,用nullptr替代NULL):

#include <cstring> // 用于memcpy
#include <new>      // 用于nothrow选项(可选,保持和C一样的NULL返回逻辑)

// 假设StackMeta_t和StackObject_t的定义如下(原C代码中应该有):
struct StackObject_t;
struct StackMeta_t {
    StackObject_t* stack;
    size_t objsize;
    size_t numelem;
};

struct StackObject_t {
    void* obj;
    StackObject_t* next;
};

StackMeta_t* mystack_create(size_t objsize)
{
    // 使用new(nothrow)避免抛出异常,保持和C一样返回NULL的逻辑
    StackMeta_t* elem = new(std::nothrow) StackMeta_t;
    if (!elem) {
        return nullptr;
    }
    elem->stack = nullptr;
    elem->objsize = objsize;
    elem->numelem = 0;
    return elem;
}

// PUSH
int mystack_push(StackMeta_t* data_stack, void* obj)
{
    if (!data_stack) {
        return -1;
    }

    StackObject_t* nodeObject = new(std::nothrow) StackObject_t;
    if (!nodeObject) {
        return -1;
    }

    // 二选一:用operator new分配内存
    nodeObject->obj = operator new(data_stack->objsize);
    // 或者用new char[]
    // nodeObject->obj = new char[data_stack->objsize];

    if (!data_stack->stack) {
        nodeObject->next = nullptr;
    } else {
        nodeObject->next = data_stack->stack;
    }
    std::memcpy(nodeObject->obj, obj, data_stack->objsize);
    data_stack->stack = nodeObject;
    data_stack->numelem++;

    return 0;
}

// 配套的销毁函数(原C代码应该有,这里补充C++版本)
void mystack_destroy(StackMeta_t* data_stack)
{
    if (!data_stack) return;
    StackObject_t* curr = data_stack->stack;
    while (curr) {
        StackObject_t* next = curr->next;
        // 对应分配方式选择释放方式:
        operator delete(curr->obj); // 对应operator new
        // delete[] static_cast<char*>(curr->obj); // 对应new char[]
        delete curr;
        curr = next;
    }
    delete data_stack;
}

关键语法说明

  1. new vs operator new:
    • new T = 调用operator new分配内存 + 调用T的构造函数
    • operator new(size_t) = 仅分配内存,无构造逻辑,完全等价于malloc
  2. new(nothrow):默认new分配失败会抛出std::bad_alloc异常,加上nothrow选项后会返回nullptr,和C的malloc行为一致,适合保持原代码的错误处理逻辑。

内容的提问来源于stack exchange,提问作者Heroking18

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 12:40:35