返回时C函数改变值。堆栈损坏?

时间:2011-11-06 18:42:20

标签: c

我今天遇到了一个非常奇怪的问题。 长话短说,我的函数返回一个值,调用者得到一个不同的值。 在我的代码附近,我打电话给:

Message* m = NULL;
m = connection_receive(c);

其中connection_receive的定义如下:

Message* connection_receive(Connection* c)
{
Message* k;

    if (c->state == CON_STATE_AUTHENTICATED)
    {
        pthread_mutex_lock(&c->mutex_in);

        if (g_queue_is_empty(c->in))
            k = NULL;
        else
            k = (Message*)g_queue_pop_head(c->in);

        pthread_mutex_unlock(&c->mutex_in);
        /* Until here, k is reachable and contains the correct data. */
        return k;
    }
    else
        return NULL; 
}

这是一个gdb运行,​​我在返回之前和分配之后就停止了:

222         return k;
(gdb) p k
$1 = (Message *) 0x7ffff0000950
(gdb) n
226 }
(gdb) n
main () at src/main.c:57
57              if (m)
(gdb) p m
$2 = (Message *) 0xfffffffff0000950

当然,如果我们尝试访问0xfffffffff0000950,我们会遇到分段错误。

如果我更改了函数而不是返回一个值,而是使用第二个参数来传递它的值,但我想知道这个值出了什么问题。

非常感谢。

编辑: 这有效,但不方便。而且我也想知道为什么会出现这种奇怪的错误。

void connection_receive2(Connection* c, Message** m)
{
    if (c->state == CON_STATE_AUTHENTICATED)
    {
        pthread_mutex_lock(&c->mutex_in);

        if (g_queue_is_empty(c->in))
            *m = NULL;
        else
            *m = (Message*)g_queue_pop_head(c->in);

        pthread_mutex_unlock(&c->mutex_in);
    }
    else
        *m = NULL;
}

EDIT2: 解决了。谢谢大家。 问题是头文件上的拼写错误。 我不能使用-Werror因为我需要做的事情 提出一些警告,并在一个大的输出和大标题我错过了。

3 个答案:

答案 0 :(得分:6)

  1. 您的m如何定义?
  2. 您的来电者是否可以访问正确的原型?
  3. 你在哪个架构上?
  4. 我怀疑这些类型不匹配,我的问题2是所有问题的关键。

    你正在返回一个指针(我猜是这样)48或64位。然而,调用者认为得到一个int,它可能有32位并且已经签名。在转换回指针时,值会进行符号扩展。

答案 1 :(得分:0)

你是否在队列中推送了malloc:ed对象?如果没有,你反而推了一个堆栈对象,那么当你弹出项目时可能会出现奇怪的行为。

答案 2 :(得分:0)

我们面临同样的问题,根本原因是函数connection_receive()的隐式声明。所以它默认为int签名然后存储在m。