Mar*_*k C 2 c null pointers variable-assignment
我正在搞乱C指针.当我编译并运行以下代码时.
例1:
#include <stdio.h>
int main()
{
int k;
int *ptr;
k = 555;
if (ptr == NULL) {
printf("ptr is NULL\n");
} else {
printf("ptr is not NULL\n");
printf("ptr value is %d\n", *ptr);
}
printf("ptr address is %p\n", ptr);
}
Run Code Online (Sandbox Code Playgroud)
我得到输出:
ptr is not NULL
ptr value is 1
ptr address is 0x7fff801ace30
Run Code Online (Sandbox Code Playgroud)
如果我没有为k赋值:
例2:
#include <stdio.h>
int main()
{
int k;
int *ptr;
if (ptr == NULL) {
printf("ptr is NULL\n");
} else {
printf("ptr is not NULL\n");
printf("ptr value is %d\n", *ptr);
}
printf("ptr address is %p\n", ptr);
}
Run Code Online (Sandbox Code Playgroud)
然后输出就像我期望的那样:
ptr is NULL
ptr address is (nil)
Run Code Online (Sandbox Code Playgroud)
同样,如果我在函数外定义变量:
例3:
#include <stdio.h>
int k;
int *ptr;
int main()
{
k = 555;
if (ptr == NULL) {
printf("ptr is NULL\n");
} else {
printf("ptr is not NULL\n");
printf("ptr value is %d\n", *ptr);
}
printf("ptr address is %p\n", ptr);
}
Run Code Online (Sandbox Code Playgroud)
输出:
ptr is NULL
ptr address is (nil)
Run Code Online (Sandbox Code Playgroud)
在第一个例子中,ptr有一个地址和值,这是预期的行为吗?如果是这样的话:
我在x64上使用Uccntu 12.04.04上的gcc进行编译:
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)
Run Code Online (Sandbox Code Playgroud)
编辑
为了清楚起见,我已将上面的例子编号.
基于Dietrich的回答,我做了一些搜索,发现了这个问题:为什么全局变量总是初始化为'0',而不是局部变量?.
C中的局部变量不会自动初始化,只会自动初始化全局变量.
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!
}
Run Code Online (Sandbox Code Playgroud)
未初始化变量的值未指定.在实践中,这可能意味着不同的事情.
如果您的编译器或运行时在使用之前将内存清零,则它可能为零.
它可以填充像哨兵0xdeadbeef或0xeeeeeeee.
它可能包含来自该特定内存位置中最后一个的垃圾.(这种方法最常见.)
您正在使用GCC,它使用第三种方法,因此您看到最后一个函数使用该内存位置的垃圾.您可以使用Valgrind运行该程序(强烈推荐),它可能会使用未初始化的内存吐出错误消息,但不能保证捕获所有错误.
一种选择是如果要使用它们,则显式初始化局部变量.
void function()
{
int *ptr = NULL;
...
}
Run Code Online (Sandbox Code Playgroud)
如果没有使用该值,我更喜欢保留未初始化的变量,因为编译器和Valgrind可以给我诊断消息,让我知道我对代码的理解是不正确的,如果事实证明使用了未初始化的内存.
| 归档时间: |
|
| 查看次数: |
1361 次 |
| 最近记录: |