2

我打电话时到底发生了什么free(a)?我知道它正在释放使用的内存,但这是否也意味着a无法再访问存储在数组中的数据(因此,无法调用copyArray)?

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);
4

7 回答 7

4

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!

于 2013-02-20T18:20:06.777 回答
1

是的,这正是它的意思。只要您调用free()有问题的内存,就会返回供操作系统使用。它可能看起来仍然有效,但是您正在导致未定义的行为。

于 2013-02-20T17:52:20.153 回答
1

您不应访问已释放的内存位置。是的,无法再访问存储在这些位置的数据。但是访问释放的位置会导致未定义的行为。

于 2013-02-20T17:52:45.647 回答
1

但这是否也意味着无法再访问存储在数组 a 中的数据

是的 - 更准确地说,访问它(即取消引用无效指针)会导致未定义的行为,因此您的程序可以做任何事情(包括崩溃,它可能会这样做)。

于 2013-02-20T17:52:48.563 回答
0

当内存被释放时,您无法对它可能包含的内容做出任何假设。所以你不应该再访问它了。

于 2013-02-20T17:52:35.403 回答
0

当你调用free(a)它意味着内存已被标记为重复使用。a因此,向其中写入数组仍然有效,但它是未定义的行为。稍后它可能会被覆盖,而不会通知您。

其次,不要malloc()在 C中转换返回值。

做这个:

int *a = malloc(sizeof(*a) * numberOfInts);

此外,在 C99 中,您可以在其中执行以下操作的 VLA 的规定:

printf("Enter array length: ");
scanf("%d",&numberOfInts);
int a[numberOfInts];

and you will not have to manually de-allocate these arrays. Note however, there is a limit to the length you can have for VLAs

于 2013-02-20T17:54:40.613 回答
0

When you are using 'malloc', you are dynamically allocating a block of memory pointed at by a. Typically, although implementation specific, dynamically allocated memory is stored on the heap. Without calling free, you will be leaking memory when a goes out of scope.

The block of memory that you created, which is pointed at by a, can no longer be used after a call to free. This would have very unpredictable behaviour and could potentially cause a segmentation fault.

于 2013-02-20T17:56:12.503 回答