如何解决C语言中的默认垃圾值?

问题描述 投票:3回答:5

如果我们在C编程中将变量声明为整数而不定义值,则printf从缓冲区中打印一些垃圾值。有什么方法可以防止打印垃圾值?

我想检查在编译时是否可以完成某些工作?如果可能的话?

c programming-languages default-value compile-time garbage
5个回答
11
投票

是。初始化变量。


1
投票

维基百科说以下内容:

在计算中,未初始化的变量是声明但未设置为确定的使用之前的已知值。它会有一些价值,但没有可预见的。因此,这是一个编程错误和常见来源软件中的错误]

因此将其初始化为默认值。


1
投票

如果要定义局部变量,则不会。编译器不会为您初始化它们。堆栈根据调用的函数及其局部变量而增长和收缩。对于编译器来说,在每次函数调用时清除所有内存是没有意义的。

但是,如果将全局变量放在.bss中,则其初始值可以为0,这是缩小程序大小的优化。


1
投票

在编译时,大多数编译器(例如GNU编译器)都可以标识未初始化变量的使用位置。但是,您可能需要设置标志,例如GNU编译器的-Wall

变量的值在这里是已经,尽管它可以是任何值。即它是变量的“初始”状态。

因此,您必须初始化变量以避免垃圾。

当声明变量x时,它已经将一个部分分配给该变量名引用的存储器&x。未初始化的值和变量已放置在内存地址中。假设您初始化了一个int类型的变量v。它分配给一个内存地址,该地址是int *类型的&v。因此,地址&v将放置在内存中未使用的开放位置。

在主函数中考虑以下代码:

int x; 
// A number of bytes (in this case, sizeof(int), usually 4 B) already allocated
// starting at a memory location &x.

printf("Value at address %p: %d", &x, x); 
// Value at &x may be any int, which is unpredictable

[编译此代码时,会出现此警告消息,其中SOME_DIRECTORY是任意目录:

SOME_DIRECTORY>gcc -Wall -g sampleprogram.c -o sampleprogram
sampleprogram.c: In function 'main':
sampleprogram.c:8:5: warning: 'x' is used uninitialized in this function [-Wuninitialized]
     printf("Value at address %p: %d", &x, x);

就像电路一样,存储器的起始值也是不可预测的。不管您的价值为何是随机垃圾。这也是undefined behavior的一种形式,这意味着C编译器国际标准没有设置任何要求,因此可能发生任何事情。这是一个非常糟糕的错误,可能会导致多个难以跟踪的错误和故障。


0
投票

您当然想编译所有警告和调试信息:gcc -Wall -Wextra -gGCC。然后很可能会收到警告,并且应该改进代码以使警告不得到。

当然,您应该初始化变量。顺便说一句,这样的初始化代码不足,并且运行非常快。并且在某些情况下(例如-O1),gcc可以优化(使用as-if rule)并删除无用的初始化。因此,根据经验,不要害怕“无用的”初始化。

您应该养成初始化大多数变量的习惯(几乎没有例外,例如,某些PRNG的种子)。在少数情况下,您不是故意初始化变量,而是希望它保留一些垃圾值,请在注释中记录下来(但不要指望垃圾是真正随机的;实际上,它仍然可能总是一样的) )。

阅读有关undefined behavior的更多信息。成为UB的scared

请记住,变量是源代码中的名称。变量在运行时不存在(仅存在位置)。它们可以由编译器删除,有时可能位于call stack调用帧的某个插槽中,可以进入某些寄存器中,等等...

© www.soinside.com 2019 - 2024. All rights reserved.