为什么我的变量未初始化?

问题描述:

我已经减少了我的代码,以最简单的方式来隔离我的问题,我想出了什么是我的问题,但我无法解决它。事实上,我甚至不知道是否有问题。为什么我的变量未初始化?

我有一个函数,意思是初始化未初始化的变量,并重新初始化已初始化的变量。 我的问题是,我声明的变量似乎被初始化。

这里是剩下的代码:

/** 
    * 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

不,它们不支持初始化为NULL,它们将具有不确定的值,因为它们具有自动存储持续时间并且未被显式初始化。

N1256 6.7.8初始化

10如果具有自动存储持续时间的对象没有被明确初始化,它的值是 不确定的。

就我所知,只有静态变量在初始化时才会设置为NULL。其他变量将指向一个随机存储器位置,并将该值存储在该存储器位置。作为使用C/C++的程序员,您需要负责内存使用以及存储在这些位置的内容(内存管理是通常使用的术语)。它不会为你做任何工作。

您的变量(tabTestAllocate)未初始化(请参阅: Why aren't pointers initialized with NULL by default?)。 这意味着它的值是未确定的。 明确地定义了它的指针(&tabTestAllocate)。 因此,在你的if语句中,td_ptr有一个定义的(不是NULL)值,而* td_ptr是未定的。但是这并不意味着* td_ptr应该是NULL,只是你不知道它是什么,所以如果条件成立或者不成立,你就无法知道先验知识。