如何用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; }
关键语法说明
newvsoperator new:new T= 调用operator new分配内存 + 调用T的构造函数operator new(size_t)= 仅分配内存,无构造逻辑,完全等价于malloc
new(nothrow):默认new分配失败会抛出std::bad_alloc异常,加上nothrow选项后会返回nullptr,和C的malloc行为一致,适合保持原代码的错误处理逻辑。
内容的提问来源于stack exchange,提问作者Heroking18
相关产品推荐
相关产品推荐

