Segfault - 但指针不是NULL

时间:2013-05-14 17:20:06

标签: c pointers memory-management segmentation-fault

我在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的整数表示时,它们是非常接近的整数。所以这些东西应该在记忆中附近。

4 个答案:

答案 0 :(得分:2)

如果编译器不知道某个函数,则假定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;
}

答案 1 :(得分:1)

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

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

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

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

答案 2 :(得分:1)

看起来你有两种类型,名称是关闭

mytypemy_type

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

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

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

答案 3 :(得分:0)

根据您的评论,fieldint所以

printf(mytype->field);

应该是

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

来自cplusplus网站的printf()页面

  

int printf(const char * format,...);

     

将格式化数据打印到stdout

     

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