C 在堆上创建数组,typedef指向它的指针,Segmentation fault:11访问它时
这个怎么了C 在堆上创建数组,typedef指向它的指针,Segmentation fault:11访问它时,c,C,这个怎么了 typedef unsigned char * test; void init_test(test t); void insert(test t); int main() { test t; init_test(t); insert(t); printf("%d\n", t[3]); return 0; } void init_test(test t) { t = (test)malloc(100 * sizeof(test
typedef unsigned char * test;
void init_test(test t);
void insert(test t);
int main() {
test t;
init_test(t);
insert(t);
printf("%d\n", t[3]);
return 0;
}
void init_test(test t) {
t = (test)malloc(100 * sizeof(test));
}
void insert(test t) {
t[0] = 200;
t[1] = 201;
t[2] = 202;
t[3] = 203;
t[4] = 204;
}
它输出203,但随后分段错误:11
这是正确版本的精简版本。在正确的版本上,在seg故障之前,我甚至没有得到值输出。这不起作用:
void init_test(test t) {
t = (test)malloc(100 * sizeof(test));
}
它不会将t
分配给调用方init_test(t)
,它只是将指针扔掉,因为参数t
超出范围,其生命周期在函数结束时结束。您必须保存malloc结果并将其传递给调用者,例如
init_test(&t);
除此之外
void init_test(test *t) {
*t = malloc(100 * sizeof **t);
}
而且不要投malloc(搜索此网站的原因)。这会奏效。您正在使用局部变量('t')
在C语言中,所有函数参数都是按值传递的。因此,您的
init_test
函数正在更新调用函数中未反映的本地值。因此,main
中的t
在该调用之后仍然未初始化。然后将此未初始化的指针传递给insert
,该指针将尝试取消引用该指针。这将调用在本例中显示为崩溃的
使用init_test
返回分配的指针,并将返回值分配给t
,而不是获取参数
因此,如下定义您的函数:
test init_test() {
test t = malloc(100 * sizeof(*t)); // not sizeof(test)
if (t==NULL) {
perror("malloc failed");
exit(1);
}
}
t = init_test();
那么就这样称呼它:
test init_test() {
test t = malloc(100 * sizeof(*t)); // not sizeof(test)
if (t==NULL) {
perror("malloc failed");
exit(1);
}
}
t = init_test();
此外,将指针隐藏在
typedef
中也不是一个好主意。它掩盖了您正在使用指针这一事实,并且可能会让代码的读者(包括您自己)感到困惑。释放您分配的内存!!!哦,就这些吗?我没有意识到不这样做会导致那样的问题。我来看看。谢谢。从我的快速浏览中,idk如果这是唯一的问题,但肯定需要解决注意:如果要使用指针typedef,请尝试将其名称弄清楚,例如“pMyDataStruct”。注意:永远不要使用typedef
对象指针。它最终会弄乱你的代码。这也使得编写const-correct代码变得不可能,或者淹没了名称空间。我试过你的建议了。总线错误:10。我更喜欢使用指针方法,而不是返回值的函数。我不能让代码在此评论中返回,将在下面发布代码。好的,谢谢。我还没试过,但可以看出它会起作用。我想在pos中使用指针,所以我坚持并希望让Jens的方法发挥作用,但现在不行。谢谢。sizeof(*test)
是一个语法错误,我猜你的意思是sizeof*t
@M.M很好。已编辑。功能参数是冗余的,应删除以避免混淆(和UB)。