通过将指针整数和 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 );
?
代码:
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 );
?