C++之一些事一些情--变量初始化

       在声明变量的时候,有的人不会对变量进行初始化,要不就是为了少输入几个字符,要不就是忘记了,可能就埋下了隐患。

1、野指针

int *ptr;	//野指针
*ptr = 10;	//修改野指针指向内存区域,有可能出现问题
       上面的代码,在声明ptr的时候没有对其进行赋NULL,当尝试修改野指针指向的内存区域,运气好的时候,赋值操作不会出现问题;运气不好的时候,就会写乱了内存,或者导致程序崩溃。

int *ptr = new int(10);
delete ptr;	//ptr所指内存被释放,但ptr指向的内存地址没变,ptr变为野指针
if (NULL != ptr)
{
    *ptr = 8;	//修改野指针ptr指向的内存区域,有可能出现问题
}
       上面的代码,当ptr被delete后,并没有对其赋NULL,当尝试修改野指针指向的内存区域,有可能出现上例的问题。

int *ptr = new int(10);
delete ptr;	//释放ptr所指内存
...
//某些逻辑
...
delete ptr;	//两次释放ptr所指内存,出现coredump,程序崩溃
       上面的代码,当ptr第一次被delete后,并没有对其赋NULL,当程序逻辑复杂的时候,程序员可能忘记了前面已经delete过了,就有可能对ptr进行第二次delete,此时就会出现coredump。如果在第一次delete之后马上给ptr赋NULL,第一次delete操作就没有问题了,因为允许对指向NULL的指针进行多次delete操作。

       指针用得好会给程序员带来非常的便利,用得不好,则会给程序员带来无尽的痛苦,对于野指针问题,要记住两点:

1) 声明一个指针的时候注意初始化为NULL

int *ptr = NULL;

2) 释放之后怎指向内存区域后,记得赋NULL

delete ptr;
ptr = NULL;


2、栈垃圾数据

void Func()
{
    int bar;
    printf("%d\n", bar);
    bar = 2;
}

int main()
{
    Func();	//输出:0
    Func();	//输出:2,此处输出的是垃圾数据
}

       上面main函数中,第一次调用Func函数时,输出为0,因为编译器给变量bar赋了一个默认值0(注意,不同的编译器的实现不一样);第二次调用Func函数时,输出为2,是一个垃圾数据,这是为什么呢?
       以gcc为例,编译器对于函数的处理是,先将当前函数后的下一条要执行的语句压栈,然后将函数返回值压栈,接着对实参从左到右求值,从右到左压栈,最后就对函数局部变量进行压栈。上面main函数中的执行流程大概如下:

       1) 第一个Func函数执行时,先将第二个Func函数调用语句压栈;
       2) 将Func函数的返回值压栈;
       3) 由于没有实参,第一个Func函数的局部变量bar将会被压栈;
       4) 由于bar没有初始化,编译器给其赋默认值0;
       5) 打印bar之后,对栈中的bar变量赋值为2;
       6) 将bar出栈;
       7) 将返回值出栈;
       8) 将第二个Func函数调用出栈;

       对于第二个Func函数的执行流程与第一个Func函数的执行流程一样,但是要注意一点是,所谓的出栈,其实只是标记对应的栈位置可以再用,并没有对里面的数据重新初始化,而第二个Func函数的局部变量bar刚好进栈位置是第一个Func函数的局部变量bar所处的位置,此时第二个bar变量的值就继承了第一个bar变量的值2,因此出现了上面main函数的输出为0和2,很明显第二个bar变量的数据是脏数据。
       如何避免这个问题呢?还是那句,初始化吧,少年,打多几个字符,幸福千万家啊,不然出现这些奇葩问题,就苦了后面来的一大堆苦b程序员啊!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值