编译器控件如何帮助分配和解分配C++内存?
How does the compiler control help in allocating & deallocating memory in C++?
我在一本C++书中读到malloc()
&free()
是liabrary函数,因此不在编译器的控制范围内。
但是,如果您有一个操作员来执行动态存储分配&初始化(new
)和另一个操作员执行清理&释放存储(delete
),编译器仍然可以保证构造函数&将为所有对象调用析构函数。
所以,我想知道编译器是如何实现的?将通知任何示例或演示。
提前谢谢。
malloc
函数返回一块连续内存,仅此而已。如何键入类型转换并使用它(用于对象)是您的问题。
而new
运算符返回在内存中分配的对象。尽管两者都返回一个指针,但最终您得到的是构造的对象,而不是C++中的原始内存。这里的重点从低级内存处理转移到对象处理,随之而来的是类型安全。这就是new
不返回void*
的原因。
此外,如果你注意到,在前一种情况下,C是一个进行分配的函数,即语言本身没有分配对象或内存的概念。而在C++中,new
是一个运算符,因此该语言本质上理解动态创建对象的含义。编译器实现了语言规定的内容,因此在发现错误时可以标记错误。
例如:
int *ptr = malloc(sizeof(char) * 4);
这里,程序员假设一个整数的大小4,虽然这在他的平台中可能是真的,但并非所有平台都是真的。从概念上讲,char
和int
是不同的类型,但C编译器忽略了类型不匹配。它所做的只是调用malloc
函数,并将返回的地址分配给ptr
。它的域到此为止,由程序员来使用(或滥用?)分配的内存。这不是编译器的错误或弱点,因为语言标准没有赋予编译器更多的权力来强制执行更多。
在C++中
int *ptr = new char[4];
将被标记为错误;正确的方法是CCD_ 14,其中类型匹配。C++更严格,在错误常见的地方允许较小的自由度,从而产生更干净的代码。类型安全可以说是C++语言最大的安全特性。出于同样的原因,类型转换有一个丑陋的语法:它们显示了设计的弱点。使用更严格的语言,编译器能够对开发人员实施更多的限制(因为人类更容易出错,所以在大多数情况下效果很好)。
编译器并没有真正直接"帮助"分配和释放内存;您的代码必须明确地执行此操作。当线程离开作用域(析构函数)时,C++语言提供了代码的确定性执行。这反过来通常用于释放堆分配的内存。
new和delete是c++中的关键词。
C++编译器会为您生成隐藏代码来处理内存分配/释放的问题。
例如,
struct Test() { }
Test *a = new Test();
编译器可能会这样做,(以下是伪代码)
Test *a = (Test *)malloc(sizeof(Test));
if (a == nullptr) { throw std::bad_alloc; }
try
{
a.Test(); //call constructor
}
catch (...)
{
//constructor exception, free the memory first, then re-throw
free(a);
throw;
}
如果是阵列,事情会更复杂,
struct Test() { }
Test *a = new Test[10];
编译器可能会这样做,
Test *a = (Test *)malloc(sizeof(Test) * 10);
if (a == nullptr) { throw std::bad_alloc; }
int i;
try
{
for (i = 0; i < 10, i++)
a[i].Test(); //call constructor
}
catch (...)
{
//call destructor for all constructed objects
for (int j = 0; j < i; j++)
a[j].~Test();
free(a);
throw;
}
类似的逻辑适用于删除。
- 将数组的地址分配给变量并删除
- vector.resize()中的分配错误
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- Win32编译器选项和内存分配
- 函数中堆分配的效果与缺少堆分配的情况
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 获取字符串的长度并将其分配给数组
- 将地址分配给本地指针后,公共对象的变量将消失
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- 我在二维向量中是否正确分配了内存
- 正在尝试重载二进制搜索树分配运算符
- GlobalAlloc而不是其他分配方法
- 自定义先决条件对移动分配运算符有效吗
- 我可以重新分配/覆盖std::字符串吗
- 在c++中使用动态分配的问题
- 编译器控件如何帮助分配和解分配C++内存?
- 为什么我可以通过重复分配和解分配内存来耗尽系统的所有内存?
- 析构函数和解分配函数的区别是什么?