假设我定义了一些类:
class Pixel {
public:
Pixel(){ x=0; y=0;};
int x;
int y;
}
Run Code Online (Sandbox Code Playgroud)
然后使用它编写一些代码.我为什么要这样做?
Pixel p;
p.x = 2;
p.y = 5;
Run Code Online (Sandbox Code Playgroud)
来自Java世界我总是写:
Pixel* p = new Pixel();
p->x = 2;
p->y = 5;
Run Code Online (Sandbox Code Playgroud)
他们基本上做同样的事情,对吗?一个在堆栈上而另一个在堆上,所以我将在以后删除它.两者之间有什么根本区别吗?为什么我更喜欢一个呢?
我来自C++背景,我和C#一起工作了大约一年.像许多其他人一样,我对于为什么确定性资源管理不是内置于语言中而感到困惑.我们没有确定性的析构函数,而是具有处置模式.人们开始怀疑是否通过他们的代码传播IDisposable癌症是值得的.
在我的C++偏见的大脑中,似乎使用带有确定性析构函数的引用计数智能指针是垃圾收集器的一个重要步骤,它需要您实现IDisposable并调用dispose来清理非内存资源.不可否认,我不是很聪明......所以我纯粹是想要更好地理解为什么事情就是这样.
如果修改了C#,那么:
对象是引用计数.当对象的引用计数变为零时,将在对象上确定性地调用资源清理方法,然后将该对象标记为垃圾回收.垃圾收集在将来某个非确定性时间发生,此时回收内存.在这种情况下,您不必实现IDisposable或记得调用Dispose.如果要释放非内存资源,则只需实现资源清理功能.
编辑:从目前为止的评论,这是一个坏主意,因为
我认为第一名是有效的,但使用弱引用很容易处理第二名.
那么速度优化是否超过你的缺点:
如果您的资源清理机制是确定性的并且内置于该语言中,则可以消除这些可能性.
似乎有两个论点为什么人们应该NULL在释放它们之后设置指针.
简短:free()不小心召唤第二次,当它被设置为时,不会崩溃NULL.
几乎总是这掩盖了一个逻辑错误,因为没有理由free()第二次调用.让应用程序崩溃并能够修复它会更安全.
它不能保证崩溃,因为有时在同一地址分配新内存.
当有两个指向同一地址的指针时,主要发生双重自由.
逻辑错误也可能导致数据损坏.
短:malloc()除非释放指针设置为,否则访问释放的指针可能会导致数据损坏,如果在同一位置分配内存NULL
NULL如果偏移足够大(someStruct->lastMember,theArray[someBigNumber]),则无法保证在访问指针时程序崩溃.而不是崩溃将导致数据损坏.
将指针设置为NULL无法解决具有相同指针值的不同指针的问题.
随意扩展这个问题.
因此,如果我理解得很好,垃圾收集会自动释放程序不再使用的对象.像java中的垃圾收集器.
我听说像C这样的语言不支持垃圾收集,程序可能会有内存泄漏并随后耗尽内存.
那么程序员在不支持垃圾收集的C语言中所犯的错误是什么?我猜不会在它们不再使用后解除分配对象.但是由于缺少垃圾收集器,这些是我们可以做的唯一错误吗?
我想释放一些我没有指针的内存块.在我的计划,我打电话malloc顺序,希望内存中创建的malloc(1),malloc(4),malloc(5)是连续的.然后,当我只有指针时,我释放这些内存malloc(5).但我想不出如何做到这一点; 我不能简单地创建一个引用ptr [-5]地址的指针,然后释放5个字节的内存?如何才能做到这一点?
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(){
malloc(1);
malloc(4);
char* ptr = malloc(5);
free(ptr);
}
Run Code Online (Sandbox Code Playgroud)