C – 检查是否分配了整数

如何确定是否取消分配整数?

int i; /* no assignment */ if (/* conditional statement here to check if int i is unassigned or not */) { printf("Integer is unassigned!\n"); } else { printf("Integer is assigned!\n"); } 

你不能。 它将具有“未定义”内容,这意味着它将包含当时在该内存位置中发生的事情。

。 。 。 除非i在全局范围内声明,否则它将初始化为零。

C本质上不支持这一点 – 就像它本身不支持对数组的边界检查一样。 这是速度/效率和安全之间的权衡。

通常……初始化变量。

这很简单。 你知道它是未分配的,因为你没有初始化它。

如果i是全局的或静态的,它的值将为0 ,否则它的值可以是任何值,并且无法确定它是否是垃圾。

如果使用未初始化的值,您可以要求编译器警告。 然而,他们并不是完全可靠的 – 你偶尔会得到误报,因为DFA并不像你希望的那样聪明,也许偶尔会出现假阴性(我希望不会,但我保证不会)。

对于GCC:

 -Wuninitialized -O1 

如果要编写条件代码:

 int a = 3; int b; int *p = (rand() > RAND_MAX/2) ? &a : &b; if (is_uninitialized(*p)) // blah 

那你运气不好 与某些动态语言不同,C没有“未定义值”的概念。 如果未初始化变量,则不会给出一些可以在以后测试的特殊值。 它根本没有给出值,因此未定义使用变量时会发生什么。

正如其他人所指出的那样,你不能编写一个C程序来检测它自己的一个变量是否未初始化,你应该努力确保变量始终被初始化。

  • 如果您的目标是确保所有变量都已初始化,那么像valgrind这样的工具可以通过昂贵的运行时分析动态检测未初始化变量的使用。

  • 如果你的目标是确保私有数据只被初始化一次,通常的方法是用它来保护它

     int i; static bool initialized = 0; ... if (!initialized) { initialized = 1; i = ... i's initial value ...; } 

与之前的所有答案一样,无法在运行时检测到这种情况。 但是,几乎所有静态代码分析工具都会警告您未分配的变量。

在初始化(或赋值)之前使用变量是导致错误的严重原因。 您无法在运行时可靠地检查它,但您可以在编译期间或之前检测它。

我建议不要在代码中检查它。 因为这可能会导致编译器警告(变量’i’在被赋值之前使用),引入新错误并且在中到大程序中成功的机会很小。

最好的方法是使用静态代码分析工具(如QA / C或PCLint)。 在高警告灵敏度级别使用编译器是一个免费选项,作为专用工具的覆盖范围要小得多。

如果执行代码审查,还可以在核对表中包含对未初始化变量的检查。 这不是保证,但它会触发审阅者的手动检查。

如果它是您想要的运行时检查,那么您可以通过将变量初始化为超出范围的值来开始。 例如-1,否则为正值。 然后你可以检查

 #define UNASSIGNED_VALUE -1 static int number_of_apples = UNASSIGNED_VALUE; if (UNASSIGNED_VALUE == number_of_apples) { // error handling } 

这不是一个真正的“未初始化”变量,但至少可以检测合法范围内的运行时分配是否已完成。

通常,C库将变量设置为0,但不一定如此。

但基本上,你不能。 在定义中为它们分配默认值,例如:

 int i = 0; /* Or what ever value you know won't be used elsewhere */ 

然后,如果您运行某些代码并想要检查是否在那里设置了值,则可以与初始值进行比较。

在C中,整数在创建时采用未定义的值。 这意味着如果您首次使用该整数来自其中包含5893872的寄存器/内存位置/设备,则该值是该整数的值。 (里程因调试/发布编译而异。)

处理此问题的常用方法是使用无意义的默认值:

 int number_of_widgets = -1; 

…或表示其状态的标志:

 int number_of_widgets; int number_of_widgets_assigned = 0; if (number_of_widgets_assigned) do something else do something else number_of_widgets_assigned = 1; 

没有其他方法可以检测是否已分配某些内容 – 除非您想进入硬件的调试function,并且我怀疑这不是此对话的内容。

检查您正在使用的变量是否在运行时初始化(分配)对于C来说是非常困难的。它没有语言支持,并且运行时可用的信息不足以完美检测未初始化的值。 诸如Valgrind / Memcheck之类的动态分析工具经历了很长的时间(例如跟踪进程地址空间中的每个内存字节,然后检查每个存储以将字节标记为intiialized)以确定是否初始化了值使用仍然容易出现误报。

如果您只是想尽量减少程序中的这些错误,那么静态分析工具(如lint)可以很好地告知您是否使用了未初始化的变量。 事实上,我相信大多数编译器都会尽力告诉你什么时候这样做(但是,它们当然不是完美的。)

在C#中我会使用:

 Nullable i = null; /* null assignment */ if (i == null) { printf("Integer is unassigned!\n"); } else { printf("Integer is assigned!\n"); } 

不过,不确定这是否会转换为C.