c - 释放其他类型的双指针时使用 void ** 是否安全?

标签 c void-pointers

我通过以下方法在 double int 指针中实例化了一个二维数组。

int **make2Dint(int rows, int columns) {
    //a is our 2D array
    int **a = (int **)calloc(rows, sizeof(int *));
    //If we can't allocate the necessary memory, return null.
    if (!a) {
        return (int **)NULL;
    }

    //Allocate each row with the correct amount of column memory.
    for (int i = 0; i < rows; i++) {
        a[i] = (int *) calloc(columns, sizeof(int));
        //If we can't allocate the necessary memory, return null.
        if (!a[i]) {
            return (int **)NULL;
        }
    }

    return a;
}

为此,我还写了一个免费的函数,如下

void free2DArray(void **a, int rows) {
    for (int i = 0; i < rows; i++) {
        free(a[i]);
    }

    free (a);
}

当要使用我的免费功能时,(通过 free2DArray(array, rows); 然而,gcc 给了我一个警告。

In file included from life.c:6:0:
twoD.h:14:6: note: expected ‘void **’ but argument is of type ‘int **’
 void free2DArray(void **a, int rows);
      ^~~~~~~~~~~

现在,我可以通过转换为 void ** 来解决这个问题,但是 this似乎表明我对 void ** 的使用有问题。

There is no generic pointer-to-pointer type in C. void * acts as a generic pointer only because conversions (if necessary) are applied automatically when other pointer types are assigned to and from void *'s; these conversions cannot be performed if an attempt is made to indirect upon a void ** value which points at a pointer type other than void *. When you make use of a void ** pointer value (for instance, when you use the * operator to access the void * value to which the void ** points), the compiler has no way of knowing whether that void * value was once converted from some other pointer type. It must assume that it is nothing more than a void *; it cannot perform any implicit conversions.

In other words, any void ** value you play with must be the address of an actual void * value somewhere; casts like (void **)&dp, though they may shut the compiler up, are nonportable (and may not even do what you want; see also question 13.9). If the pointer that the void ** points to is not a void *, and if it has a different size or representation than a void *, then the compiler isn't going to be able to access it correctly.

但是,由于我没有取消对这个指针的引用,所以我不确定它是否有问题。有人可以解释它是否有问题,为什么?

最佳答案

没有。即使指针类型具有相同的大小和表示形式,除少数特殊情况外,C 也不允许不同类型别名,并且编译器可以并且将会假设这一点进行转换(优化)。如果你真的想要这样一个通用的自由循环,你可以把循环放在一个宏中,这个宏在它具有正确指针类型的上下文中(在调用者中)展开,但你真的应该避免“深”伪二维数组

关于c - 释放其他类型的双指针时使用 void ** 是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48471805/

相关文章:

c - 函数 deque 到数组不起作用

正确关闭工作窃取线程池

ios - 是否可以在不搜索 select/create 的情况下识别 sqlite3_step 执行的查询类型(select、create 等)?

将 long 转换为 (void *) 以传递

c - 使用 (void *) 作为通用数据容器时的左值问题

C:使用 void 指针的通用数据结构的更好语法?

c++ - 如何打印/访问 const void 指针的内容?

c - 识别 Windows 中进程加载的所有模块

c - 为 gtk_overlay 添加背景颜色

c - fatal error : i2c/smbus. h : No such file or directory?