Valgrind"条件跳跃或移动取决于未初始化的值"错误

时间:2014-06-09 23:27:05

标签: c pointers valgrind

我是C编程的新手(关于stackoverflow的第一个问题!) - 我试图拼凑一个简单的链表实现和valgrind开始标记错误,声明我使用的是未经过消毒的值。这是我的代码,有一些打印试图帮助我看看触发问题的原因:

#include <stdio.h>

struct s
{
    int value;
};

struct s *init(int value);

int main(void)
{
    struct s *ptr = init(6);
    printf("In main, ptr->value=%d\n", ptr->value);
    struct s example = *ptr;
    printf("In main, example.value=%d\n", example.value);
    return 0;
}

struct s *init(int valueToSet)
{
    struct s example;
    example.value = valueToSet;
    printf("In init, example.value=%d\n", example.value);

    struct s *ptr = &example;   
    printf("In init, ptr->value=%d\n", ptr->value);

    return ptr;
}

和valgrind的输出:

==8002== Memcheck, a memory error detector
==8002== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==8002== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==8002== Command: ./ptr
==8002== 
In init, example.value=6
In init, ptr->value=6
==8002== Invalid read of size 4
==8002==    at 0x8048401: main (ptrproblem.c:13)
==8002==  Address 0xbe8e6088 is just below the stack ptr.  To suppress, use: --workaround-gcc296-bugs=yes
==8002== 
In main, ptr->value=6
==8002== Invalid read of size 4
==8002==    at 0x8048418: main (ptrproblem.c:14)
==8002==  Address 0xbe8e6088 is just below the stack ptr.  To suppress, use: --workaround-gcc296-bugs=yes
==8002== 
In main, example.value=-1097965404
==8002== 
==8002== HEAP SUMMARY:
==8002==     in use at exit: 0 bytes in 0 blocks
==8002==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==8002== 
==8002== All heap blocks were freed -- no leaks are possible
==8002== 
==8002== For counts of detected and suppressed errors, rerun with: -v
==8002== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

所以看起来当我直接使用结构时,没有问题,如果我创建一个指向结构的指针并直接使用它,它也很好。但是,当我将指针传递回main并以相同的方式使用它时,根据valgrind(即使它打印正确的值)它是不正确的,然后当我取消引用指针时它显然没有指向预期的内存。我希望自己做了些蠢事,但我看不清楚 - 你能帮帮我吗?

2 个答案:

答案 0 :(得分:3)

init返回的值不是有效指针,因此取消引用它是未定义的行为。这是因为它是局部变量的地址,当函数返回时它不再存在。

关于C的任何基础教程或教科书都应该涵盖这个基本主题以及如何设计这样的代码。 (您需要动态内存分配。)

答案 1 :(得分:0)

你的指针ptr被分配给一个局部变量的地址,该变量在函数完成后将不再存在...

 struct s *init(int valueToSet)
{ 
  struct s *ptr = (struct s*) malloc(sizeof(struct s));
  ptr->value = valueToSet;
  return ptr;
}

你必须添加

   #include <stdlib.h> 
开始时也是......