当前位置: 首页 > news >正文

c++中局部变量初始化的问题

在C语言里,全局变量如果不初始化的话,默认为0,也就是说在全局空间里:

int x =0; 跟 int x; 的效果看起来是一样的。但其实这里面的差别很大,强烈建议大家所有的全局变量
都要初始化,他们的主要差别如下:

编译器在编译的时候针对这两种情况会产生两种符号放在目标文件的符号表中,对于初始化的,叫强
符号,未初始化的,叫弱符号。连接器在连接目标文件的时候,如果遇到两个重名符号,会有以下处理规
则:
1、如果有多个重名的强符号,则报错。
2、如果有一个强符号,多个弱符号,则以强符号为准。

3、如果没有强符号,但有多个重名的弱符号,则任选一个弱符号。
大部分情况下,我们不希望连接器为我们做决定,所以我不是很认同后两个规则,至少应该给个警告,
而不应该安静地通过。因为这种问题引起的bug会很难查,所以我们要尽量把全局变量初始化,对于不想给
别的文件引用的变量,也尽量用static修饰。

除了连接时的表现不一样外,未初始化的符号在目标文件的bss段中,而初始化的符号在data段中。

注: bss段(未手动初始化的数据)并不给该段的数据分配空间,只是记录数据所需空间的大小。
data段(已手动初始化的数据)则为数据分配空间,数据保存在目标文件中。
对于局部变量,不被初始化的话,其值一般分为两种情况Debug版和Release版的区别。
例:
#include "stdafx.h"
int i;
int main(int argc, char* argv[])
{
printf(" i = %d\n",i);
int j;
printf(" j= %d\n",j);
return 0;
}
在Debug版下,在这段代码中i的值打印出来是0,而j的值打印出来是-858993460,也就是0xCCCCCCCC.
至于为什么是这个值,有网友给出这个解释。(设计成0xcccccccc是有特殊用意的……这个好像叫做
Poison,未初始化的Pointer去取值的话会出错。肯定有人问为什么不弄成0x00000000,因为空指针是指
针的有效状态,可能会误导人,而0xCCCCCCCC在Windows下永远不可能是一个指针的有效状态(不是NULL,
不指向一个对象,不指向一堆对象紧接之后的区域),这就是在模拟野指针……)
值得注意的是,同样的代码在Release版下,这段代码中未被初始化的变量最后打印出来的可能都是0。
也有强大的网友给出解释。(重点在于vc的一个功能:Catch release-build errors in debug build用
/GZ编译开关打开。debug版这个开关是开的,release版是关的(为了效率)。这个开关说白了就是把所有
动态局部变量初始化成0xcccccccc,把所有动态堆变量初始化成0xcdcdcdcd。很多新手会忘记初始化这些
本来应该初始化的变量(尤其是new出来的变量),有时他们会假定这些变量应该是0,这样就可能出现在
release版正常而debug版不正常的程序,因为release版至少局部变量的初始值很可能就是0,而有时他们
又会假定或者期望这些变量不是0,这样就带了一个最难发现的bug)

From:http://www.kingofcoders.com/viewNews.php?type=newsCpp&id=189&number=4836955386

-------------------------------------------------------------------------------------------------------------------------------------

不过个人去验证局部变量,没初始化,访问会直接编译不过。

相比类里的成员对象没初始化变量的值也分对象构建的方式而不同:
struct Npc
{
int m;
int data;
};
Npc* pNpc = new Npc; // new Npc()
printf("m default value = %d\n", pNpc->m);
Npc()会调用默认构造函数,会对成员变量初始化0,new Npc则不会,data的值会是不确定的。

转载于:https://www.cnblogs.com/bile/p/8625498.html

相关文章:

  • WordCount
  • 外卖也智能!美团骑手智能助手的技术与实践
  • 【协议转换和消息路由】camel-spring-boot-starter 实践
  • 坑货!阿里奇门中心
  • [ssh]如何设计ARM板上多用户key登录系统
  • 71. Simplify Path
  • numpy 数组运算
  • Java 选择排序selection sort
  • 磁盘管理
  • 利用SCVMM 2012 R2来管理Azure虚拟机
  • AlphaGo告诉我们人工智能成功的五大秘诀,AI下一个风口在哪里?
  • 互联网面临新挑战,区块链经济将兴起
  • 2016年全球IDC市场规模达到451.9亿美元,增速达17.5%
  • YII2中查询生成器Query()的使用
  • notepad++(NPP) 任意多光标编辑,超越列块模式
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • eclipse(luna)创建web工程
  • golang 发送GET和POST示例
  • gops —— Go 程序诊断分析工具
  • HTTP请求重发
  • iOS仿今日头条、壁纸应用、筛选分类、三方微博、颜色填充等源码
  • Java 实战开发之spring、logback配置及chrome开发神器(六)
  • javascript从右向左截取指定位数字符的3种方法
  • Linux链接文件
  • Redash本地开发环境搭建
  • Spring Cloud中负载均衡器概览
  • XForms - 更强大的Form
  • 分享自己折腾多时的一套 vue 组件 --we-vue
  • - 概述 - 《设计模式(极简c++版)》
  • 马上搞懂 GeoJSON
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 爬虫进阶 -- 神级程序员:让你的爬虫就像人类的用户行为!
  • 盘点那些不知名却常用的 Git 操作
  • 前端技术周刊 2019-02-11 Serverless
  • 删除表内多余的重复数据
  • hi-nginx-1.3.4编译安装
  • 新年再起“裁员潮”,“钢铁侠”马斯克要一举裁掉SpaceX 600余名员工 ...
  • 整理一些计算机基础知识!
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • #WEB前端(HTML属性)
  • #调用传感器数据_Flink使用函数之监控传感器温度上升提醒
  • #鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行
  • (办公)springboot配置aop处理请求.
  • (分布式缓存)Redis哨兵
  • (七)Knockout 创建自定义绑定
  • (十三)Maven插件解析运行机制
  • (一) springboot详细介绍
  • (转)Linq学习笔记
  • .NET 表达式计算:Expression Evaluator
  • .Net 访问电子邮箱-LumiSoft.Net,好用
  • .NET/MSBuild 中的发布路径在哪里呢?如何在扩展编译的时候修改发布路径中的文件呢?
  • [14]内置对象
  • [GDMEC-无人机遥感研究小组]无人机遥感小组-000-数据集制备
  • [GXYCTF2019]BabyUpload1 -- 题目分析与详解
  • [HCTF 2018]WarmUp (代码审计)