用C调用free() [英] Calling free( ) in C

查看:177
本文介绍了用C调用free()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我完全新的C.这个问题似乎很傻,但这里有云...

 为int * A =(INT *)malloc的(的sizeof(int)的* numberOfInts);
对于(i = 0; I< numberOfInts;我++){
        一个由[i] =随机();
        的printf(%d个\\ N,一个[我]);
    }
    自由(一);
    copyArray(* a ++,numberOfInts);

到底是什么,当我拨打免费发生(一)?我知道它正在释放所使用的存储器,但是这也意味着,存储在阵列的数据的不再能访问(因此,不能够调用copyArray)?


解决方案

  

什么,当我拨打免费到底正在发生(一)?


这是具体实现。作为一个例子,在Linux和glibc,几件事情可以发生:

如果内存在的128K以上的块分配,的glibc 将已分配了一个新的内存区域(特别是写入时复制 MMAP 为/ dev> /零)。当它被释放,存储区被简单地释放(则munmap 'd)和消失。进一步的访问将会崩溃。

如果分配的内存较小,它会在堆上。堆是起始于一个固定的地址,一个内存区域,是一个大小,该过程可以缩小或增加(与 SBRK )的。

内存分配器保留其中的这个区域的部分被分配轨道。东西被分配在第一时间,堆的尺寸增加,并且存储器被附加到结束在这个新的空间。

如果您免费这样的内存块,在堆底,堆的大小可以减少,从而使记忆无效,并进一步使访问崩溃。分配器不会增加或虽然减小堆大小只有几个字节,因此在该点它取决于分配的大小和释放的块的数量。这可能是访问,它可能不是。

如果您分配内存十个​​街区并释放第9名,你最终在堆未使用的区域。既然你只能通过设置结束地址修改堆大小,你真的不能做任何事情。内存仍然有效,并访问它仍然可以工作。你可能会发现,即使你的原始数据,它,就能继续仿佛什么都没有发生过。

不过,由于新的内存分配,的malloc 会尽量把它放在这个未使用的区域,从而让其他数据覆盖什么最初那里。然后在free'd阵列设置一个int可能会覆盖一个指针在程序的一个完全无关的部分,欢闹和调试随之而来。

TL;博士:不要访问free'd内存

I'm completely new at C. This question might seem silly, but here it goes...

int *a = (int *) malloc(sizeof(int) * numberOfInts);
for (i = 0; i < numberOfInts; i++) {
        a[i] = random();
        printf("%d\n", a[i]);
    }
    free(a);
    copyArray(*a++, numberOfInts);

What exactly is happening when I call free(a)? I know it is freeing the memory used, but does this also mean that the data stored in array a can no longer be accessed (therefore, not being able to call copyArray)?

解决方案

What exactly is happening when I call free(a)?

This is implementation specific. As an example, with Linux and glibc, one of several things can happen:

If the memory was allocated in a block of 128k or more, glibc will have allocated a new memory area (specifically, a copy-on-write mmap of /dev/zero). When it's freed, the memory area is simply deallocated (munmap'd)and disappears. Further accesses will crash.

If the allocated memory was smaller, it will go on the heap. The heap is a single memory area starting at a fixed address, and is of a size that the process can shrink or increase (with sbrk).

The memory allocator keeps tracks of which pieces of this area is allocated. The first time something is allocated, the size of heap is increased, and the memory is appended to the end in this new space.

If you free such a block of memory, at the end of the heap, the heap size can be reduced, thus making the memory invalid and making further accesses crash. The allocator will not increase or decrease the heap size for just a few bytes though, so at that point it depends on the size of the allocation and the number of blocks freed. It might be accessible, and it might not be.

If you allocate ten blocks of memory and free the first nine, you end up with an unused area in the heap. Since you can only modify the heap size by setting the end address, you can't really do anything about it. The memory is still valid, and accessing it will still work. You will probably even find your original data in it, and will be able to continue as if nothing happened.

However, as new memory is allocated, malloc will try to put it in this unused area, thus letting other data overwrite what was originally there. Setting an int in your free'd array could then overwrite a pointer in a completely unrelated part of your program, and hilarity and debugging ensues.

tl;dr: Don't access free'd memory!

这篇关于用C调用free()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆