【问题标题】:Segfault -- but the pointer isn't NULL [closed]段错误——但指针不是 NULL [关闭]
【发布时间】:2013-05-09 02:04:38
【问题描述】:

我在 C 语言中执行以下操作:

void *initialize()
{
    my_type *ret = malloc(sizeof(my_type));
    return (void*)ret;
}

void test()
{
    my_type* ret = (mytype*)initialize();
    my_type x = *ret;
}

它在取消引用时崩溃:

Received signal 11 (Segmentation fault: 11)

指针不为空:我尝试打印指针,得到了一个值。

我还尝试在测试函数中创建一个新的 my_type,如下所示:

my_type* new = malloc(sizeof(my_type));

当我打印 new 和 ret 的整数表示时,它们是彼此非常接近的整数。所以这些东西在内存中应该就在附近。

【问题讨论】:

  • printf 需要格式说明符 mytype->field 的类型是什么?
  • mytype->field的值是多少?
  • field的类型是什么
  • 您使用mytype->field 作为格式字符串,这可能不是您想要做的。
  • 不应该是printf("%d", ret->field);吗?

标签: c pointers memory-management segmentation-fault


【解决方案1】:

如果编译器不知道某个函数,它会将int 假定为其返回类型。

如果int 的大小与函数实际返回的大小不同,编译器生成的代码可能会错过返回正确的字节数。

但是,您发布的代码是正确的,并且会按预期执行,因为 initialise() 在使用它之前出现,因此编译器已经知道函数返回哪种类型。

最可能的是原始代码(您发布了不是)看起来像这样(没有initialise() 的原型):

尝试以下方法:

#include <stdlib.h> /* To pull in malloc's protoype. */

void * initialize(void);

void test()
{
    my_type x, * ret = initialize();
    if (ret)
      x = *ret;
}

void * initialize(void)
{
    my_type * ret = malloc(sizeof(*ret));
    return ret;
}

【讨论】:

    【解决方案2】:

    field 可能是 (a) 一个 char 数组,(b) 一个指向 char 的指针,或者 (c) 一个整数值。是吗?

    在所有三种情况下,printf() 语句都期望field 是指向空终止字符串的指针。至少在您提供的示例代码中,它没有被初始化为任何东西。

    所以... SIGSEGV 是因为 (a) field 是一个未初始化的 char 数组,谁知道 printf() 正在读取多远的内存以寻找空终止符,(b) 字段是一个未初始化的指针...仅仅因为它不为零,并不意味着它是一个有效的内存地址,或者 (c) 您试图将整数或其他值作为指向 char 的指针传递给 printf(),但事实并非如此.

    这三个中的任何一个都会产生您报告的结果。

    【讨论】:

      【解决方案3】:

      看起来你有 2 种名称很接近

      mytypemy_type

      my_type *ret = malloc(sizeof(mytype));
      

      my_type* ret = (mytype*)initialize();
      

      可能是您对同一类型使用了 2 个不同的名称的错字。这可能会导致崩溃

      【讨论】:

        【解决方案4】:

        根据您的评论,fieldint 所以

        printf(mytype->field);
        

        应该是

        printf("%d\n", ret->field);
        

        来自 cplusplus 网站中的printf() 页面

        int printf ( const char * 格式, ... );

        将格式化数据打印到标准输出

        将 format 指向的 C 字符串写入标准输出 (stdout)。如果 format 包含格式说明符(以 % 开头的子序列),则 format 后面的附加参数将被格式化并插入到结果字符串中,替换它们各自的说明符。

        【讨论】:

          猜你喜欢
          • 2021-04-10
          • 1970-01-01
          • 1970-01-01
          • 2018-05-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-12-05
          相关资源
          最近更新 更多