0

我在 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

4 回答 4

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;
}
于 2013-05-14T17:41:18.100 回答
1

看起来您有 2 种名称接近的类型

mytypemy_type

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

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

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

于 2013-05-14T17:33:48.713 回答
1

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

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

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

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

于 2013-05-14T17:24:14.187 回答
0

根据你的评论,fieldint这样的

printf(mytype->field);

应该

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

来自cplusplus 站点的printf()页面

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

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

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

于 2013-05-14T17:24:33.417 回答