【问题标题】:Weird bug while passing double pointers to a function in C将双指针传递给C中的函数时出现奇怪的错误
【发布时间】:2020-10-08 13:07:43
【问题描述】:

错误:
在将双指针传递给函数时,指针指向的字段的值似乎取决于函数的某些局部变量。
更具体地说,当我评论 L 行时(在函数“函数”中)
输出:

In the main function: 1
In the function: 1

但是当我取消注释同一行时,
输出:

In the main function: 1
In the function: 0

程序:

typedef struct s{
    int *value; 
}s;


s** initialize()
{
    s** temp = (s**)malloc(sizeof(s*));
    s* f = (s*)malloc(sizeof(s));
    f->value = NULL;
    temp = &f;
    return temp;
}

void function(s** what)
{

//Line L:   size_t count = 0;
    printf("In the function: %d\n", (*what)->value == NULL);
}

int main()
{
    s** m = initialize();
    printf("In the main function: %d\n", (*m)->value == NULL);
    function(m);
}

我尝试过的:

  • 我以为我得到的是随机输出,但事实并非如此,因为我一直得到相同的输出。
  • 我尝试破译汇编语言代码,但这对我来说太神秘了。

环境:

  • 编译器:gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
  • 操作系统:linux mint

【问题讨论】:

标签: c pointers memory-leaks undefined-behavior dereference


【解决方案1】:

这里:

s** initialize()
{
    s** temp = (s**)malloc(sizeof(s*));
    s* f = (s*)malloc(sizeof(s));
    f->value = NULL;
    temp = &f;          // temp is now the address of a local variable
    return temp;        // now temp is returned
                        // that's undefined behavior when the returned
                        // pointer is used
}

initialize 函数返回时变量f 不存在,因此您返回的是不存在变量的地址。使用地址将是未定义的行为,即任何事情都可能发生,一般无法解释。

在特定系统上,我们可以做一些猜测。我的猜测是,一旦您添加了带有新变量的行,它就会覆盖以前存储f 的内存位置。如果没有新变量,以前存储 f 的位置仍然相同。

【讨论】:

  • 啊——你比我快了一分钟。
【解决方案2】:

函数initialize

s** initialize()
{
    s** temp = (s**)malloc(sizeof(s*));
    s* f = (s*)malloc(sizeof(s));
    f->value = NULL;
    temp = &f;
    return temp;
}

可以调用未定义的行为,因为它返回指向局部变量的指针。而且它还有内存泄漏。

首先分配了一块内存,并将其地址分配给变量 temp

    s** temp = (s**)malloc(sizeof(s*));

然后指针被重新赋值

    temp = &f;

所以分配的内存没有被释放。

指针由局部变量的地址赋值

    s* f = (s*)malloc(sizeof(s));
    //...
    temp = &f;

退出函数后,变量f 将不再存在。所以指针 temp 的值无效。

看来你的意思是如下

s** initialize()
{
    s** temp = (s**)malloc(sizeof(s*));
    s* f = (s*)malloc(sizeof(s));
    f->value = NULL;
    *temp = f;
    return temp;
}

如果进行更改,您将获得预期的结果。

#include <stdio.h>
#include <stdlib.h>

typedef struct s{
    int *value; 
}s;

s** initialize()
{
    s** temp = (s**)malloc(sizeof(s*));
    s* f = (s*)malloc(sizeof(s));
    f->value = NULL;
    *temp = f;
    return temp;
}

void function(s** what)
{

//Line L:   size_t count = 0;
    printf("In the function: %d\n", (*what)->value == NULL);
}

int main( void )
{
    s** m = initialize();
    printf("In the main function: %d\n", (*m)->value == NULL);
    function(m);

    free( *m );
    free( m );
}

程序输出是

In the main function: 1
In the function: 1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 2011-05-19
    • 1970-01-01
    相关资源
    最近更新 更多