2014-06-09 72 views
1

我很新C編程(我的第一個問題在stackoverflow!) - 我試圖拼湊一個簡單的鏈表實現和valgrind開始標記說明我正在使用未經初始化的值。這裏是我的代碼,一些印刷,試圖幫我看看是什麼原因引發的問題: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

從書中學習。在{}}中定義的變量在到達'}'後不再存在(除非它們被聲明爲「靜態」)。 –

回答

3

init返回的值不是有效的指針,所以它是未定義的行爲來取消引用它。這是因爲它是局部變量的地址,當函數返回時它不再存在。

關於C的任何基本教程或教科書都應該涵蓋這個基本主題以及如何設計這樣的代碼。 (您需要動態內存分配。)

+0

當然 - 謝謝你Kerrek和馬特。知道這將是簡單的事情! – user3724090

0

指針PTR被分配到一個局部變量將在功能完成後不再存在的地址...

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

你必須添加

#include <stdlib.h> 

在開始還...

相關問題