加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

为什么我会收到警告:(接近初始化’ptr’)和运行时的分段错误,当

发布时间:2020-12-16 10:01:38 所属栏目:百科 来源:网络整理
导读:这是以下代码: 当我尝试访问数组的第一个值时,为什么它会给出分段错误? 这些警告是什么? #includestdio.hint main(void){ int *ptr = {1,2,3,4,5};//Is it not similar to char *ptr="Stackoverflow"? printf("%dn",*ptr);// why Segmentation fault(cor
这是以下代码:
当我尝试访问数组的第一个值时,为什么它会给出分段错误?
这些警告是什么?

#include<stdio.h>
int main(void)
{
    int *ptr = {1,2,3,4,5};//Is it not similar to char *ptr="Stackoverflow"?
    printf("%dn",*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,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]

解决方法

您的原始代码无效.它至少包含两个约束违规:它为不存在的对象提供初始化器,并尝试为int *对象使用初始化器1(int类型).编译器可以(和恕我直言)应该拒绝它.在仅仅警告错误之后编译代码时,gcc过于宽松.生成的代码具有未定义的行为.

const char *cptr = "Hello";

以上是有效的. “Hello”是数组类型的表达式(特别是char [6]类型).在大多数情况下,包括这个,这样的表达式被隐式转换为指向数组的第0个元素的指针.请注意,我添加了const,因此如果我尝试修改cptr指向的数据,编译器将至少发出警告.

int *iptr = { 1,5 }; // invalid

这是无效的.您可能希望它的处理方式与cptr类似.问题是{1,5}不是表达;它仅在初始化程序中有效.它可能是数组对象的有效初始值设定项,但由于它不是表达式,因此数组到指针转换规则不适用.

假设您的编译器支持C99或更高版本(特别是复合文字功能),您可以编写:

int *iptr = (int[]){ 1,5 };

(这不是强制转换;语法类似,但{…}不是表达式.)

复合文字是数组类型的表达式,特别是int [5],并且数组到指针的转换适用.

需要注意的是:字符串文字会创建一个数组对象,并且该对象具有静态存储持续时间,这意味着它在整个程序执行期间都存在.复合文字只有在任何函数外出现时才会创建一个具有静态存储持续时间的对象;在函数内部,它创建一个具有自动存储持续时间的对象,这意味着当它到达当前块的末尾时它将不再存在.在这种情况下,它在main函数内定义,所以它不太可能是一个问题.但值得注意的是.例如,这是安全的:

const char *new_string(void) {
    const char *result = "hello";
    return result;
}

但这不是:

int *new_array(void) {
    int *result = (int[]){ 1,5 };
    return result; /* BAD! */
}

因为离开函数时数组不再存在.为避免这种情况,您可以显式创建数组对象以使其成为静态:

int *new_array(void) {
    static const int arr[] = { 1,5 };
    int *result = arr; /* or &arr[0] */
    return result;     /* or "return arr;" */
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读