通过将指针整数和 sizeof(int) 相乘来使用 realloc 不起作用

Using realloc by multiplying a pointer integer and sizeof(int) not working

代码:

void main() {
    int *array = calloc(5, sizeof(int));
    int *amount = 9;
    array[0] = 1;
    array[1] = 2;
    array[3] = 5;

    int i = 0;
    while (i < 5) {
        printf("%d ", array[i]);
        i += 1;
    }

    printf("%d", amount); //Printing
    array = realloc(array, amount * sizeof(int)); //Problem is here
    printf("\n");
    i = 0;
    while (i < 9) {
        printf("%d ", array[i]);
        i += 1;
    }
    free(array);
}

它说 "invalid operands to binary * (have 'int *' and 'unsigned int'), but when I tried printing "amount”,实际上是 9?我正在尝试使用指针整数,以便我可以通过引用传递它。

您只是在使用这样一个事实,即您的实现允许在指针和整数之间进行安全转换,但是:

int *amount = 9;      // only use that for memory mapped hardware registers
printf("%d", amount); //re-interpreting the pointer value as an int
array = realloc(array, amount * sizeof(int));   // hopefully you got a diagnostic

太可怕了。指针应该只是指向有效对象的空指针。句号。指针运算只在数组内部才有意义。

如果一个变量应该包含整数值,那么它应该是整数类型:

int amount = 9;
printf("%d", amount); //Printing
array = realloc(array, amount * sizeof(int)); //Problem is here

如果您需要指向它的指针,只需声明它并使用它作为指针:

int amount = 9;
int *p_amount = &amount;
printf("%d - %d\n", amount, *p_amount); //Printing
array = realloc(array, (*p_amount) * sizeof(int)); //No problem now

amount 具有类型 int *printf 打印 9 的原因不是 amount 指向值 9,而是将值 9 转换为指针。

现在在您的 array = realloc(array, amount * sizeof(int)); 声明中。您尝试乘以指针(而不是 amount 指向的值)。问问自己它的语义应该是什么。而不是 int *amount = 9; 你可能想要

int *amount = calloc(1, sizeof(int));
*amount = 9;

声明一个指针并为一个整数分配 space 而不是 array = realloc(array, amount * sizeof(int)); 你可能想要

array = realloc(array, *amount * sizeof(int));

你应该尝试学习指针的概念和指针运算。仅仅声明一个指针并不会在它的末尾保留 space。

amount 应定义为 int 而不是 int *.

int amount = 9;

几件事:

首先,

int *amount = 9;

不一样
*amount = 9;

在第一种情况下,* 只是表示 amount 具有指针类型,我们正在初始化 pointer 值(即,地址)到 9,这很可能不是有效的指针值,并且尝试取消引用它可能会导致运行时错误。

在第二种情况下,我们将整数值 9 分配给 amount 指向的对象。

当你将 amount 传递给 printf 时,为什么这个没有中断?基本上,您通过传递错误类型的参数调用了未定义的行为(%d 期望 int,而您传递了 int *)。未定义行为的可能结果之一是获得预期结果。无论出于何种原因,printf 能够将 int * 值视为 int。大多数编译器应该标记该类型不匹配,但您可能需要注意提高警告级别才能看到它。

二进制 * 运算符有一个约束,即两个操作数都具有算术类型。 int * 不是算术类型,因此是诊断。

根据您在代码中实际使用 amount 的方式,您不应将其声明为指针,而应将其声明为常规 int:

int amount = 9;

其次,一般来说,你不想把realloc的结果赋值给原始指针。如果 realloc 失败,它将 return NULL 并保持原始内存块不变。但是,如果您将 NULL 分配回您的原始指针,您将失去对该内存的任何访问权限。最佳做法是将realloc的结果赋值给一个临时的,然后在赋回原来的之前验证临时有效:

int *tmp = realloc( array, amount * sizeof *array );
if ( tmp )
{
  array = tmp;
}
else
{
  // handle realloc error
}

请注意使用 sizeof *array 而不是 sizeof (int)sizeof 是一元运算符 * 或一元运算符 +,其操作数可以是带括号的类型名称或表达式。 表达式 *array 的类型为 int,因此 sizeof *array == sizeof (int)。这有助于使代码更易于阅读,并且如果您更改 array 的类型(例如 double *),则不必更新 realloc 调用。它在分配多维数组类型时也非常有用——would you rather write

int (*arr)[10] = malloc( sizeof (int) * 10 * rows);

int (*arr)[10] = malloc( sizeof *arr * rows );

?