2016-02-19 50 views
0

我已經減少了我的代碼,以最簡單的方式來隔離我的問題,我想出了什麼是我的問題,但我無法解決它。事實上,我甚至不知道是否有問題。爲什麼我的變量未初始化?

我有一個函數,意思是初始化未初始化的變量,並重新初始化已初始化的變量。 我的問題是,我聲明的變量似乎被初始化。

這裏是剩下的代碼:

/** 
    * This software defines the type TabDyn and gives the tools to manipulate it 
    * 
    * TabDyn is conceptually an array of integers. The first element is the size while the others are the members of the array. 
    * 
    * Here are the function provided to manipulate TabDyn : 
    *  td_clear(TabDyn* td) : Create the TabDyn object if non existant and initialize it to an empty one. If it exists, it empties it. 
    * 
    */ 

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

// TabDyn[0] := size 
// tabDyn[i] := i^th element of the array, first index being 1 (i>1) 
typedef int* TabDyn; 

/** 
    * param - TabDyn* td_ptr : address of a declared int 
    * void : initialize {td_ptr} to an empty array (size=0, no member) 
    */ 
void td_clear(TabDyn* td_ptr) 
{ 
    //this is the size of each member of TabDyn and thus the size of an empty TabDyn 
    size_t TabDynByteCount = sizeof(int); 

    //We must free initialized TabDyn variables 
    if(td_ptr && *td_ptr) 
    { 
     printf("INITIALIZED!\n"); //#TOREMOVE# 
     free(*td_ptr); 
    } 

    //Create TabDyn object of size = 0 and give it to param 
    *td_ptr = calloc(1, TabDynByteCount); 
} 

/** 
    * Contains various test of the TabDyn function to ensure a correct behaviour by testing it at runtime with Valgrind 
    */ 
int main() 
{ 
    //* TEST decl-init-free #VALID:v0.04# 
    printf("\n--- TEST OF td_clear BATCH 1 ---\n"); 
    printf("Declaring TabDyn variable\n"); 
    TabDyn tabTestAllocate; 
    printf("Initialising TabDyn variable\n"); 
    td_clear(&tabTestAllocate); 
    printf("Freeing now useless variables\n"); 
    free(tabTestAllocate); 
    //*/ 
    //* TEST decl-init-init-free 
    printf("\n--- TEST OF td_clear BATCH 2 ---\n"); 
    printf("Declaring TabDyn variable\n"); 
    TabDyn tabTestAllocate2; 
    printf("Initialising TabDyn variable\n"); 
    td_clear(&tabTestAllocate2); 
    printf("Re-initialising TabDyn variable\n"); 
    td_clear(&tabTestAllocate2); // It is not a duplicate 
    printf("Freeing now useless variables\n"); 
    free(tabTestAllocate2); 
    //*/ 
} 

,這裏是什麼Valgrind的說一下吧:

--- TEST OF td_clear BATCH 1 --- 
Declaring TabDyn variable 
Initialising TabDyn variable 
==10875== Conditional jump or move depends on uninitialised value(s) 
==10875== at 0x400654: td_clear (in /home/adrien/Documents/c/examen) 
==10875== by 0x4006CD: main (in /home/adrien/Documents/c/examen) 
==10875== 
INITIALIZED! 
==10875== Conditional jump or move depends on uninitialised value(s) 
==10875== at 0x4C2CDE1: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==10875== by 0x40066E: td_clear (in /home/adrien/Documents/c/examen) 
==10875== by 0x4006CD: main (in /home/adrien/Documents/c/examen) 
==10875== 
==10875== Invalid free()/delete/delete[]/realloc() 
==10875== at 0x4C2CE2B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==10875== by 0x40066E: td_clear (in /home/adrien/Documents/c/examen) 
==10875== by 0x4006CD: main (in /home/adrien/Documents/c/examen) 
==10875== Address 0x400540 is in the Text segment of /home/adrien/Documents/c/examen 
==10875== at 0x400540: _start (in /home/adrien/Documents/c/examen) 
==10875== 
Freeing now useless variables 

--- TEST OF td_clear BATCH 2 --- 
Declaring TabDyn variable 
Initialising TabDyn variable 
==10875== Conditional jump or move depends on uninitialised value(s) 
==10875== at 0x400654: td_clear (in /home/adrien/Documents/c/examen) 
==10875== by 0x40070D: main (in /home/adrien/Documents/c/examen) 
==10875== 
INITIALIZED! 
==10875== Conditional jump or move depends on uninitialised value(s) 
==10875== at 0x4C2CDE1: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==10875== by 0x40066E: td_clear (in /home/adrien/Documents/c/examen) 
==10875== by 0x40070D: main (in /home/adrien/Documents/c/examen) 
==10875== 
==10875== Invalid free()/delete/delete[]/realloc() 
==10875== at 0x4C2CE2B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==10875== by 0x40066E: td_clear (in /home/adrien/Documents/c/examen) 
==10875== by 0x40070D: main (in /home/adrien/Documents/c/examen) 
==10875== Address 0xffefffe70 is on thread 1's stack 
==10875== 
Re-initialising TabDyn variable 
INITIALIZED! 
Freeing now useless variables 
==10875== 
==10875== HEAP SUMMARY: 
==10875==  in use at exit: 0 bytes in 0 blocks 
==10875== total heap usage: 3 allocs, 5 frees, 12 bytes allocated 
==10875== 
==10875== All heap blocks were freed -- no leaks are possible 
==10875== 
==10875== For counts of detected and suppressed errors, rerun with: -v 
==10875== Use --track-origins=yes to see where uninitialised values come from 
==10875== ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 0 from 0) 

,但如果我明確初始化我的變量爲NULL,有ISN」不再有任何問題:

TabDyn tabTestAllocate = NULL; 
TabDyn tabTestAllocate2 = NULL; 

是不是m y變量應該初始化爲NULL?或者是我的if語句不測試我認爲測試的內容?

+2

不要'typedef'指針!這通過隱藏語義來模糊你的代碼,並且容易出錯。 – Olaf

回答

9

不,它們不支持初始化爲NULL,它們將具有不確定的值,因爲它們具有自動存儲持續時間並且未被顯式初始化。

N1256 6.7.8初始化

10如果具有自動存儲持續時間的對象沒有被明確初始化,它的值是 不確定的。

1

就我所知,只有靜態變量在初始化時纔會設置爲NULL。其他變量將指向一個隨機存儲器位置,並將該值存儲在該存儲器位置。作爲使用C/C++的程序員,您需要負責內存使用以及存儲在這些位置的內容(內存管理是通常使用的術語)。它不會爲你做任何工作。

1

您的變量(tabTestAllocate)未初始化(請參閱: Why aren't pointers initialized with NULL by default?)。 這意味着它的值是未確定的。 明確地定義了它的指針(&tabTestAllocate)。 因此,在你的if語句中,td_ptr有一個定義的(不是NULL)值,而* td_ptr是未定的。但是這並不意味着* td_ptr應該是NULL,只是你不知道它是什麼,所以如果條件成立或者不成立,你就無法知道先驗知識。