C 函数在返回时更改值。损坏的堆栈?

标签 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;
}

编辑2: 解决了。谢谢大家。 问题是头文件中的错字。 我不能使用 -Werror 因为我需要做一些事情 提出一些警告,在一个大的 make 输出和大的标题中我错过了它。

最佳答案

  1. 您的m 是如何定义的?
  2. 您的来电者是否可以访问正确的原型(prototype)?
  3. 您使用的是什么架构?

我怀疑类型不匹配,我的问题 2 是问题的症结所在。

您正在返回一个(我想是)48 或 64 位的指针。然而,调用者想要得到一个 int,它可能有 32 位并且是有符号的。在转换回指针时,该值会进行符号扩展。

关于C 函数在返回时更改值。损坏的堆栈?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8029412/

相关文章:

c++ - long long 到 long double 的转换

c - scanf 来自函数的结构,从同一函数调用以扫描其他结构

c++ - C/C++ 位数组或位 vector

c++ - 什么是数组到指针的衰减?

c++ - vector 迭代自身

c - 使用 memset 初始化 float 组

c - printf 不打印正确的浮点值

c - sscanf 目标地址溢出

比较 Haskell 和 C 计算素数的速度

c - 为什么我不能将二维数组传递给这个定义的函数?