【问题标题】:How to solve default garbage values in C?如何解决 C 中的默认垃圾值?
【发布时间】:2010-08-11 09:25:58
【问题描述】:

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

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

【问题讨论】:

    标签: c programming-languages default-value compile-time garbage


    【解决方案1】:

    是的。初始化变量。

    【讨论】:

    • 我只会将 intilization 用作编译器选项(不同的值,例如 0、1、0xFF)用于测试目的。
    • @mielacademy:始终至少将-O -Wall 传递给gcc,然后它会警告未初始化变量等常见错误。另见stackoverflow.com/questions/3375697/useful-gcc-flags-for-c
    • 您不应该使用编译器选项来解决 coed 中的错误。毫无疑问,使用未初始化的变量 is 是一个错误。
    • 该死的错字。顺便说一句,我曾经在我的男女同校中有一个错误,但一些青霉素解决了它。
    【解决方案2】:

    维基百科是这样说的:

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

    所以将其初始化为默认值。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

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

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

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

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

        在 main 函数中考虑这段代码:

        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);
        

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

        【讨论】:

          【解决方案5】:

          您当然希望在编译时包含所有警告和调试信息:gcc -Wall -Wextra -gGCC。那么你很可能会收到警告,你应该改进你的代码以得到任何警告。

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

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

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

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

          【讨论】:

            猜你喜欢
            • 2016-08-08
            • 2016-01-17
            • 1970-01-01
            • 2012-09-15
            • 2013-05-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多