为什么我会收到警告:(接近初始化'ptr')和运行时的分段错误,当指针上有值时?

gee*_*ngh 3 c arrays pointers initialization

这是以下代码:当我尝试访问数组的第一个值时,为什么它会给出分段错误?这些警告是什么?

#include<stdio.h>
int main(void)
{
    int *ptr = {1,2,3,4,5};//Is it not similar to char *ptr="Stackoverflow"?
    printf("%d\n",*ptr);// why Segmentation fault(core dumped) instead of 1
    return 0;
}

...
output:

warning: initialization makes pointer from integer without a cast [enabled by default] 
int *ptr = {1,2,3,4,5};
^

warning: (near initialization for ‘ptr’) [enabled by default]
warning: excess elements in scalar initializer [enabled by default]
warning: (near initialization for ‘ptr’) [enabled by default]
warning: excess elements in scalar initializer [enabled by default]
warning: (near initialization for ‘ptr’) [enabled by default]
warning: excess elements in scalar initializer [enabled by default]
warning: (near initialization for ‘ptr’) [enabled by default]
warning: excess elements in scalar initializer [enabled by default]
warning: (near initialization for ‘ptr’) [enabled by default]
Run Code Online (Sandbox Code Playgroud)

Sou*_*osh 5

//它与char*ptr ="Stackoverflow"不相似吗?

TL; DR不,不是.


使用的初始化{1,2,3,4,5}程序称为括号封闭的初始化程序,它应该初始化元素类型的值.这用于聚合或联合类型类型,如C11章节§6.7.9,初始化中所述

具有聚合或联合类型的对象的初始化程序应该是元素或命名成员的初始化程序的括号括起列表.

这里,初始化列表包含所有int值,并且您正在尝试初始化pointer它.这是错的.

另外,关于标量类型,引用C11,章节§6.2.5

算术类型和指针类型统称为标量类型.[...]

聚合类型

[...]数组和结构类型统称为聚合类型.

这里有很多问题,比如

  1. 您正在使用int值来初始化int *.
  2. 您最终会提供一个 括号括起来的列表,其中包含多个标量对象的初始化元素.

所以,稍后在你的代码中,

 printf("%d\n",*ptr);
Run Code Online (Sandbox Code Playgroud)

本质上是一个无效的内存访问,它调用未定义的行为.分割错误是许多副作用之一.

即将发表评论,

char*ptr ="Stackoverflow"?

在这种情况下char *ptr="Stackoverflow";,这里"Stackoverflow"称为字符串文字,并且使用字符串文字ptr的基址进行初始化.


解:

你需要有一个阵列intS的可以初始化使用括号内的初始化.沿途的东西

 int ptr[] = {1,2,3,4,5};
Run Code Online (Sandbox Code Playgroud)

将是有效的.那你可以像使用它一样

 for(int i = 0; i < 5; i++)
    printf("%d\t", *(ptr+i));
Run Code Online (Sandbox Code Playgroud)