是否可以在没有 for 循环的情况下释放 2D 数组?

Is it possible to release the 2D array without a for loop?

提问人:Zhiren Zhou 提问时间:10/2/2023 最后编辑:ChrisZhiren Zhou 更新时间:10/2/2023 访问量:96

问:

#include <stdio.h>
#include <stdlib.h>

void* create2dArray(int r,int c) {
    int (*arr)[c] = (int(*)[c])malloc(sizeof(*arr) * r);
    return arr;
}

void release2dArray(void* arr) {
    free(arr);
}

int main() {
    int r = 10, c = 20;
    int (*arr)[c] = (int (*)[c])create2dArray(r, c);
    for (int i = 0; i < r; i++) {
        for (int j = 0; j < c; j++) {
            arr[i][j] = i * c + j;
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
    release2dArray(arr);
    arr[0][2] = 20;
    printf("%d ", arr[1][2]);
}

在代码中,我使用指向数组的指针为 2D 数组分配连续内存。要释放内存,我想直接使用 release2dArray(arr),因为我知道内存分配的信息存储在分配的内存本身之前的某个地方。我认为它应该有效,但它失败了。那么我是否可以在不将该数组的形状传递到函数 release2dArray() 并且不使用 for 循环的情况下释放 2D 数组的内存?

数组 C 空闲

评论

1赞 Barmar 10/2/2023
您没有正确创建它。您分配了一个指针数组,但从未为这些行分配任何内存。填充数组的循环具有未定义的行为。r
3赞 dbush 10/2/2023
分配/取消分配是可以的。您正在尝试在释放内存后使用内存。
1赞 Support Ukraine 10/2/2023
@Barmar 分配似乎很好。 是指向 int 数组的指针。arrc
1赞 chux - Reinstate Monica 10/2/2023
@Barmar 未分配 r 指针数组int (*arr)[c] = (int(*)[c])malloc(sizeof(*arr) * r);
1赞 Support Ukraine 10/2/2023
引用:“我知道释放内存后,我不应该使用数组指针 arr 再次访问内存,这会导致未定义的行为。好吧,那么当你已经知道你不应该这样做时,你为什么要这样做呢?

答:

2赞 2 revschux - Reinstate Monica #1

“但是,如果发布成功,我认为除了 arr[0][2] 之外,所有元素都应该为 0。”

不,不要指望。之后,没有定义的方式可以使用其旧值。不要尝试通过 之后的指针进行访问,除非稍后为其分配了分配的内存。release2dArray(arr);arrfree()

    release2dArray(arr);

    // Do not attempt the following code.
    // It is undefined behavior (UB).
    //arr[0][2] = 20;
    //printf("%d ", arr[1][2]);

我是否可以在不将该数组的形状传递到函数 release2dArray() 且不使用 for 循环的情况下释放 2D 数组的内存?

是的。OP的这部分代码很好。

void release2dArray(void* arr) {
    free(arr);
}

    ... 
    release2dArray(arr); // Just fine

顺便说一句,OP分配得很好。

  • 次要:不需要石膏。

  • 次要:考虑调整数组大小。这种类型既不太窄也不太宽。size_t

// void* create2dArray(int r, int c) {
void* create2dArray(size_t r, size_t c) {
    // int (*arr)[c] = (int(*)[c])malloc(sizeof(*arr) * r);
    int (*arr)[c] = malloc(sizeof *arr * r);
    return arr;
}