开发者社区> 问答> 正文

“ int * nums = {5,2,1,4}”导致分段错误

int *nums = {5, 2, 1, 4}; printf("%d\n", nums[0]); 导致段错误,而

int nums[] = {5, 2, 1, 4}; printf("%d\n", nums[0]); 没有。现在:

int *nums = {5, 2, 1, 4}; printf("%d\n", nums); 打印5。

基于此,我猜想数组初始化符号{}将数据盲目地加载到左侧的任何变量中。当它为int []时,将根据需要填充数组。当它为int *时,指针将被5填充,并且指针存储之后的内存位置将被2、1和4填充。因此nums [0]尝试取消引用5,从而导致段错误。

如果我错了,请纠正我。如果我是正确的,请详细说明,因为我不明白为什么数组初始化程序会以它们的方式工作。 问题来源于stack overflow

展开
收起
保持可爱mmm 2020-02-08 14:35:11 649 0
1 条回答
写回答
取消 提交回答
  • C语言中有一个(愚蠢的)规则,说任何普通变量都可以用大括号括起来的初始化程序列表进行初始化,就好像它是一个数组一样。

    例如,您可以编写int x = {0};,这完全等同于int x = 0;。

    因此,在编写时,您int *nums = {5, 2, 1, 4};实际上是在为单个指针变量提供一个初始化器列表。但是,它只是一个变量,因此只会分配第一个值5,其余的列表将被忽略(实际上,我不认为带有过多初始值设定项的代码甚至不应该使用严格的编译器进行编译)-不会完全写入内存。该代码等效于 int *nums = 5;。也就是说,nums应该指向address 5。

    此时,您应该已经收到了两个编译器警告/错误:

    在不强制转换的情况下将整数分配给指针。 初始化程序列表中的多余元素。 然后,当然,代码将崩溃并烧毁,因为5很可能不是您可以取消引用的有效地址nums[0]。

    附带说明,您应该printf使用说明%p符指向指针地址,否则将调用未定义的行为。

    我不太确定您要在这里做什么,但是如果要设置一个指向数组的指针,则应该执行以下操作:

    int nums[] = {5, 2, 1, 4}; int* ptr = nums;

    // or equivalent: int* ptr = (int[]){5, 2, 1, 4}; 或者,如果您要创建一个指针数组:

    int* ptr[] = { /* whatever makes sense here */ };

    2020-02-08 14:35:25
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载