面试题答案
一键面试- 使用
malloc
分配内存- 节点创建与初始化:
malloc
只负责分配内存,返回void*
类型。例如:
- 节点创建与初始化:
struct Node {
CustomClass data;
Node* next;
};
Node* nodePtr = (Node*)malloc(sizeof(Node));
- 这里只是分配了内存空间,对于`CustomClass`对象,由于`malloc`不会调用构造函数,`CustomClass`对象处于未初始化状态。如果`CustomClass`构造函数有一些初始化操作(如初始化成员变量等),则需要手动调用构造函数来初始化对象。可以使用placement new来实现:
new (nodePtr) Node();
- 内存管理:
- 释放内存时,需要先手动调用析构函数来清理
CustomClass
对象的资源,然后再调用free
释放内存。例如:
- 释放内存时,需要先手动调用析构函数来清理
nodePtr->~Node();
free(nodePtr);
- 潜在问题:如果忘记手动调用析构函数,`CustomClass`对象中的资源(如动态分配的内存等)可能不会被正确释放,导致内存泄漏。同时,如果手动调用析构函数的顺序不正确,或者在错误的情况下调用,可能会导致程序崩溃。
2. 使用new
分配内存
- 节点创建与初始化:
new
不仅分配内存,还会调用构造函数进行对象初始化。例如:
Node* nodePtr = new Node();
- 这里`Node`对象(包括其中的`CustomClass`对象)会自动调用相应的构造函数进行初始化,无需额外手动操作。
- 内存管理:
- 释放内存时,使用
delete
操作符,它会自动调用析构函数来清理对象资源,然后释放内存。例如:
- 释放内存时,使用
delete nodePtr;
- 潜在问题:如果在析构函数中存在异常处理不当的情况,可能会导致程序在`delete`时出现未定义行为。同时,如果使用`new[]`分配数组对象,释放时必须使用`delete[]`,否则可能导致内存泄漏。
总体而言,使用new
和delete
在对象的创建和释放过程中更符合面向对象编程的习惯,自动调用构造函数和析构函数减少了手动操作的繁琐和出错的可能性。而malloc
和free
则需要更多手动干预来确保对象的正确初始化和资源释放。