未设置的 C 指针不为空 [英] An unset C pointer is not null

查看:19
本文介绍了未设置的 C 指针不为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理 C 指针.当我编译并运行以下代码时.

I am messing around with C pointers. When I compile and run the following code.

示例 1:

#include <stdio.h>

int main()
{
    int k;
    int *ptr;
    k = 555;
    if (ptr == NULL) {
        printf("ptr is NULL
");
    } else {
        printf("ptr is not NULL
");
        printf("ptr value is %d
", *ptr);
    }
    printf("ptr address is %p
", ptr);
}

我得到输出:

ptr is not NULL
ptr value is 1
ptr address is 0x7fff801ace30

如果我不给 k 赋值:

If I don't assign a value to k:

示例 2:

#include <stdio.h>

int main()
{
    int k;
    int *ptr;
    if (ptr == NULL) {
        printf("ptr is NULL
");
    } else {
        printf("ptr is not NULL
");
        printf("ptr value is %d
", *ptr);
    }
    printf("ptr address is %p
", ptr);
}

然后输出如我所料:

ptr is NULL
ptr address is (nil)

同样,如果我在函数外定义变量:

Similarly if I define the variables outside the function:

示例 3:

#include <stdio.h>

int k;
int *ptr;

int main()
{
    k = 555;
    if (ptr == NULL) {
        printf("ptr is NULL
");
    } else {
        printf("ptr is not NULL
");
        printf("ptr value is %d
", *ptr);
    }
    printf("ptr address is %p
", ptr);
}

输出:

ptr is NULL
ptr address is (nil)

在第一个例子中,ptr 有一个地址和值,这是预期的行为吗?如果是这样:

In the first example, where ptr has an address and value, is this expected behaviour? If so then:

  • 为什么 ptr 有地址和值?
  • 这些是从哪里来的,是什么设置的?
  • 如何在本地范围内正确定义空指针并在我准备使用之前将它们保持为空?

我正在 x64 上的 Ubuntu 12.04.04 上使用 gcc 进行编译:

I am compiling with gcc on Ubuntu 12.04.04 on x64:

root@dev:~# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

编辑

为了清楚起见,我在上面对示例进行了编号.

I have numbered my examples above for clarity.

基于迪特里希的回答,我做了一些搜索,发现了这个问题:为什么全局变量总是初始化为0",而不是局部变量?.

Based on Dietrich's answer I did a bit of searching and found this question: Why are global variables always initialized to '0', but not local variables?.

推荐答案

C中的局部变量不会自动初始化,只有全局变量会自动初始化.

Local variables in C are not automatically initialized, only global variables are automatically initialized.

int x; // 0 by default
static int y; // 0 by default

void function()
{
    static int z; // 0 by default
    int w; // Not initialized!  Could be anything!
}

未初始化变量的值是未指定.实际上,这可能意味着不同的事情.

The value of an uninitialized variable is unspecified. In practice, this can mean different things.

  • 如果您的编译器或运行时在使用前将内存清零,则它可能为零.

  • It may be zero, if your compiler or runtime zeroes memory before it is used.

它可能会填充像 0xdeadbeef0xeeeeeeee 这样的标记.

It may be filled with a sentinel like 0xdeadbeef or 0xeeeeeeee.

它可能包含来自该特定内存位置最后一个的垃圾.(这种方法是最常见的.)

It may contain garbage from whatever was last in that particular memory location. (This approach is the most common.)

您正在使用 GCC,它使用第三种方法,因此您会看到最后一个函数中使用该内存位置的垃圾.您可以使用 Valgrind 运行该程序(强烈推荐),它可能会吐出使用未初始化内存的错误消息,但不能保证捕获所有错误.

You are using GCC, which uses the third approach, so you are seeing garbage from the last function to use that memory location. You can run the program with Valgrind (highly recommended), and it will probably spit out error messages for using the uninitialized memory, although it is not guaranteed to catch all errors.

如果您打算使用局部变量,一个选择是显式初始化它们.

One option is to explicitly initialize local variables if you are going to use them.

void function()
{
    int *ptr = NULL;
    ...
}

如果未使用该值,我更愿意保留未初始化的变量,因为编译器和 Valgrind 可以给我诊断消息,让我知道我对代码的理解不正确,如果结果证明使用了未初始化的内存.

I prefer to leave variables uninitialized if the value is not used, since the compiler and Valgrind can give me diagnostic messages letting me know that my understanding of the code is incorrect, if it turns out that the uninitialized memory is used.

这篇关于未设置的 C 指针不为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆