0%

C++ 中 new-delete 与 malloc-free 的比较

new-delete 与 malloc-free

new&delete 与 malloc&free 的比较

  • malloc/free 是 C 语言的库函数
  • new/delete new[]/delete[] 是 C++ 中的运算符
  • malloc/free 只是申请内存空间,释放空间
  • new/delete 不仅会申请内存空间, 还会根据类型初始化内存空间,this 指针绑定, 调用构造函数和析构函数进行初始化或者清理等操作

这里有两张网上找到的图

  1. new/delete 实现

  2. new[]/delete[] 实现

不一定完全正确,但具有一定参考意义,new[] 文中说会多申请 4 字节 空间,在开始位置存储对象个数,这里我在 64 位 编译环境下验证了一下, 是前 8 字节 空间中存储的,应该与系统位数有关

测试环境: Win10 64 bit & GCC 8.1.0 64 bit

这里定义一个 Test 类作测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Test
{
public:
static int index;
Test()
{
x = ++index;
str = str + std::to_string(x);
std::cout << "Test Constructor() this=" << this << std::endl;
}
~Test()
{
std::cout << "Test Destructor() this=" << this << std::endl;
}
void Show()
{
std::cout << "Test show x(" << x << "), str(" << str << ")" << std::endl;
}
private:
int x;
std::string str {"sssaaa"};
};

int Test::index = 0;

测试:

1
2
3
4
5
6
7
8
int main(int, char**)
{
int size = sizeof(Test);
Test* p = new Test[3]();
uint64_t* sp = (uint64_t*)p - 1;
std::cout << "Test obj size: " << *sp << std::endl;
delete[] p;
}

输出如下

1
2
3
4
5
6
7
Test Constructor() this=0x1d1e88
Test Constructor() this=0x1d1eb0
Test Constructor() this=0x1d1ed8
Test obj size: 3
Test Destructor() this=0x1d1ed8
Test Destructor() this=0x1d1eb0
Test Destructor() this=0x1d1e88

如果我们修改一下上面的测试代码,更改一下前面的对象个数

1
2
3
4
5
6
7
8
9
int main(int, char**)
{
int size = sizeof(Test);
Test* p = new Test[3]();
uint64_t* sp = (uint64_t*)p - 1;
std::cout << "Test obj size: " << *sp << std::endl;
*sp = 2;
delete[] p;
}

运行结果如下

1
2
3
4
5
6
Test Constructor() this=0x6e1e88
Test Constructor() this=0x6e1eb0
Test Constructor() this=0x6e1ed8
Test obj size: 3
Test Destructor() this=0x6e1eb0
Test Destructor() this=0x6e1e88

delete[] 只执行了两次析构