Kri*_*rma 5 c++ malloc free memory-management
我遇到了一个我无法解决的问题.
我的问题是,如果我malloc以前分配内存然后内存块被删除使用delete?一般的拇指规则是
如果我们使用malloc分配内存,则应使用free删除它.
如果我们使用new分配内存,则应使用delete删除它.
现在,为了检查如果我们反过来会发生什么,我写了一个小代码.
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
class A
{
int p=10;
public:
int lol() {
return p;
}
};
int main()
{
int *a = (int *)malloc(sizeof(int)*5);
for(int i=0; i<4; i++) {
a[i] = i;
cout << a[i] << endl;
}
delete(a);
// Works fine till here..
A b;
cout << b.lol() << endl;
free(b); // Causes error.
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
错误:无法将参数'1'的'A'转换为'void*'为'void free(void*)'
我无法理解为什么会这样.请解释.
Xin*_*ang 18
当你调用delete指针时,编译器会dtor自动为你调用类,但free不会.(new也会打电话ctor给班级,malloc不会.)
在您的示例中,char数组显然没有dtor,因此delete只会返回内存.这就是为什么它没关系.(或者反之,新的char数组然后释放它.)
但是仍然存在一个问题:如果new并且malloc正在从不同的堆管理器中借用内存呢?
想象一下,你从A人那里借钱,然后再回到B人身上.即使你对此感到满意,你有没有考虑过A的感觉?
顺便说一下,你应该使用delete [] pArray;释放分配的数组new[].
free函数需要一个指向malloc分配的内存的指针.编译器只是告诉你没有传递指针,这是一个很容易证明的事实.我猜你的意思是用new创建一个对象,然后在该对象的地址上调用free.但你没有打电话给新人.
当你纠正这个问题时,你很可能会发现自由成功,但你不应该在任何这样的成功中读到任何有意义的东西.您知道规则,它们在您的文档中明确说明.做你正在尝试的事情是不正确的.行为未定义.这样的实验几乎没有什么可以获得的.您将无法了解为什么C内存管理功能无法与C++内存管理功能配对.
你的实验的问题是没有力量.您可以只显示一个特定方案的结果.但这些功能旨在全面运作.您如何测试每一种可能的情况?
切勿使用反复试验进行编程.你必须始终了解你所做的事情背后的规则和原则.
您的b变量不是指针,而是堆栈分配的A。如果你想尝试这个实验,那么你会想说
A* b = new A;
free(b);
Run Code Online (Sandbox Code Playgroud)
我完全赞成实验,但我不确定你想在这里实现什么目标。
在 C++ 中,operator new不仅分配内存,还运行构造函数。同样,delete为您运行析构函数(考虑多态类),并释放返回的内存。另一方面,malloc()和free()只是 C 库例程,它们(从程序员的角度来看)只不过是从操作系统请求一块内存,然后将其返还。
现在,对于具有简单构造函数和析构函数的简单 POD 类,您可能能够避免混合 C 和 C++ 内存分配,因为不需要执行任何特定于 C++ 的操作。但即使你这样做了,又能证明什么呢?这是未定义的行为,并且可能无法在其他编译器上工作。明天可能就不行了。
如果你使用任何 C++ 功能——继承、虚函数等,它肯定不会工作,因为除了分配内存之外new还delete必须做更多的工作。
所以,请大家一定要遵守规则!:-)