为什么我的变量没有初始化?
why are my variables not initialized?
我已将我的代码简化为最简单的代码以隔离我的问题,我弄清楚我的问题是什么,但我无法解决它。其实我也不知道有没有问题
我有一个函数,用于初始化未初始化的变量并重新初始化已初始化的变量。 我的问题是我声明的变量似乎被初始化了。
下面是代码的剩余部分:
/**
* 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,就不会有任何问题了:
TabDyn tabTestAllocate = NULL;
TabDyn tabTestAllocate2 = NULL;
我的变量不是应该初始化为 NULL 吗?还是我的 if 语句没有测试我认为它测试的内容?
不,不支持将它们初始化为 NULL
,并且它们将具有不确定的值,因为它们具有自动存储持续时间并且未明确初始化。
N1256 6.7.8 初始化
10 If an object that has automatic storage duration is not initialized explicitly, its value is
indeterminate.
据我所知,只有静态变量会在初始化时设置为 NULL。其他变量将指向随机内存位置,值存储在该内存位置。作为使用 C/C++ 的程序员,您要对内存使用情况以及存储在这些位置的内容负责(内存管理是通常使用的术语)。它不会为您做任何这些工作。
您的变量 (tabTestAllocate) 未初始化(参见:
Why aren't pointers initialized with NULL by default?)。
这意味着它的价值是不确定的。
明确定义了指向它的指针 (&tabTestAllocate)。
所以在你的 if 语句中 td_ptr 有一个定义的(不是 NULL)值,而 *td_ptr 是不确定的。但这并不意味着 *td_ptr 应该为 NULL,只是你不知道它是什么,所以你无法先验地知道条件是否为真。
我已将我的代码简化为最简单的代码以隔离我的问题,我弄清楚我的问题是什么,但我无法解决它。其实我也不知道有没有问题
我有一个函数,用于初始化未初始化的变量并重新初始化已初始化的变量。 我的问题是我声明的变量似乎被初始化了。
下面是代码的剩余部分:
/**
* 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,就不会有任何问题了:
TabDyn tabTestAllocate = NULL;
TabDyn tabTestAllocate2 = NULL;
我的变量不是应该初始化为 NULL 吗?还是我的 if 语句没有测试我认为它测试的内容?
不,不支持将它们初始化为 NULL
,并且它们将具有不确定的值,因为它们具有自动存储持续时间并且未明确初始化。
N1256 6.7.8 初始化
10 If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.
据我所知,只有静态变量会在初始化时设置为 NULL。其他变量将指向随机内存位置,值存储在该内存位置。作为使用 C/C++ 的程序员,您要对内存使用情况以及存储在这些位置的内容负责(内存管理是通常使用的术语)。它不会为您做任何这些工作。
您的变量 (tabTestAllocate) 未初始化(参见: Why aren't pointers initialized with NULL by default?)。 这意味着它的价值是不确定的。 明确定义了指向它的指针 (&tabTestAllocate)。 所以在你的 if 语句中 td_ptr 有一个定义的(不是 NULL)值,而 *td_ptr 是不确定的。但这并不意味着 *td_ptr 应该为 NULL,只是你不知道它是什么,所以你无法先验地知道条件是否为真。