如何分配给函数中未初始化的指针变量?
How to assign to to an uninitialized pointer variable in a function?
我想让这个程序合法且正确:
#include <assert.h>
#include <stdlib.h>
#define SOME_INT 5
void assign_to_x(??) {
???
}
void main(void){
int *x;
assign_to_x(?);
assert(*x == SOME_INT);
// potential cleanup
}
最初 x
指向某个位置,这样我就无法在不导致未定义行为的情况下取消引用它。所以在 assign_to_x
中我不能只把 SOME_INT
放到它指向的位置。那我有什么选择?
我看到的一个选项是:
void assign_to_x(int **x) {
*x = (int *)malloc(sizeof(int *));
**x = SOME_INT;
}
void main(void){
int *x;
assign_to_x(&x);
assert(*x == SOME_INT);
free(x);
}
然而,这似乎有点矫枉过正。
我能想到的另一件事是:
void assign_to_x(int **x) {
static int y = SOME_INT;
*x = &y;
}
void main(void){
int *x;
assign_to_x(&x);
assert(*x == SOME_INT);
}
但这真的有效吗?是否有不同的规范选项?
如果static int
解决方案满足你的程序需求,那么用那个解决方案就可以了。重要的是要注意,如果程序后来被修改,以至于它需要 *x
的多个实例,比如说因为它被重新设计为使用多个线程来完成某些工作,那么 static int
解决方案将会中断,除非也修改了
malloc
解决方案有一个错误; sizeof(int *)
应该具有 int
的大小,而不是指向 int
.
的指针的大小
否则,malloc
解决方案不是over-engineered,只是在C中不需要强制转换; *x = (int *)malloc(sizeof(int));
可以是 *x = malloc(sizeof **x);
。这是允许的,因为 C 允许将 malloc
return 的 void *
类型隐式转换为 int *
。这是首选,因为如果程序员不小心未能声明 malloc
(如包含 <stdlib.h>
),它将允许编译器产生警告。 (由于 C 开发的历史,一些编译器会为 malloc
生成 int
return 类型的默认声明,然后显式强制转换会将此 int
到 int *
。如果没有转换,编译器将针对 int
到 int *
的不正确分配发出警告。)
使用 sizeof **x
也比 sizeof(int *)
更好,因为如果 x
稍后更改为其他类型,例如 double **x
,sizeof
也不需要改;它自动遵循 x
.
的类型
我想让这个程序合法且正确:
#include <assert.h>
#include <stdlib.h>
#define SOME_INT 5
void assign_to_x(??) {
???
}
void main(void){
int *x;
assign_to_x(?);
assert(*x == SOME_INT);
// potential cleanup
}
最初 x
指向某个位置,这样我就无法在不导致未定义行为的情况下取消引用它。所以在 assign_to_x
中我不能只把 SOME_INT
放到它指向的位置。那我有什么选择?
我看到的一个选项是:
void assign_to_x(int **x) {
*x = (int *)malloc(sizeof(int *));
**x = SOME_INT;
}
void main(void){
int *x;
assign_to_x(&x);
assert(*x == SOME_INT);
free(x);
}
然而,这似乎有点矫枉过正。
我能想到的另一件事是:
void assign_to_x(int **x) {
static int y = SOME_INT;
*x = &y;
}
void main(void){
int *x;
assign_to_x(&x);
assert(*x == SOME_INT);
}
但这真的有效吗?是否有不同的规范选项?
如果static int
解决方案满足你的程序需求,那么用那个解决方案就可以了。重要的是要注意,如果程序后来被修改,以至于它需要 *x
的多个实例,比如说因为它被重新设计为使用多个线程来完成某些工作,那么 static int
解决方案将会中断,除非也修改了
malloc
解决方案有一个错误; sizeof(int *)
应该具有 int
的大小,而不是指向 int
.
否则,malloc
解决方案不是over-engineered,只是在C中不需要强制转换; *x = (int *)malloc(sizeof(int));
可以是 *x = malloc(sizeof **x);
。这是允许的,因为 C 允许将 malloc
return 的 void *
类型隐式转换为 int *
。这是首选,因为如果程序员不小心未能声明 malloc
(如包含 <stdlib.h>
),它将允许编译器产生警告。 (由于 C 开发的历史,一些编译器会为 malloc
生成 int
return 类型的默认声明,然后显式强制转换会将此 int
到 int *
。如果没有转换,编译器将针对 int
到 int *
的不正确分配发出警告。)
使用 sizeof **x
也比 sizeof(int *)
更好,因为如果 x
稍后更改为其他类型,例如 double **x
,sizeof
也不需要改;它自动遵循 x
.