C语言定义数组问题

vc++中,我定义了chara【10】,按理说是不是应该有啊a【0】-a【9】是个单元哪,但是我调试的时候发现居然分配了a【10】,而且这个单元有时候还可以用,用来存最后... vc++中,我定义了char a【10】,按理说是不是应该有啊a【0】-a【9】是个单元哪,但是我调试的时候发现居然分配了a【10】,而且这个单元有时候还可以用,用来存最后的一个\0。本人菜鸟,但是很喜欢扣细节,大家谁有相关经验来说说吧,学习一下 展开
 我来答
百度网友cbd9f66f0
2014-08-21
知道答主
回答量:19
采纳率:100%
帮助的人:14.8万
展开全部
你这种抠细节的精神很好,我来告诉你正确答案。
如果你是定义char a[10],那么你确保能使用的内存单元就是a[0]~~a[9],但是C编译器不会对数组下标进行检查,因此a[10]不会报错,并被编译为a[9]之后的那个内存单元。
你定义a[10]的时候通常由于内存对齐等原因分配的内存会不止10bytes,因此编译器实际上是为a[10]分配了内存的,因此a[10]可用,并不会对你的程序造成逻辑错误。

如果愿意,可以再进一步挖掘一下:
char a[10];
char b[10];
memset(b , 1 , 25);
这个时候对b操作超过了实际b的长度,你会发现居然改到了a的内存区域!!呵呵,这就是stack overflow黑客最常用的攻击手段。
上面的回复你认真揣摩,希望能对你有用
追问
恩很厉害,大致意思和楼下的是一样的,代码也跑的通,但是不用memset函数直接对b赋多于十个的值就不会影响到a,出现了楼下那种代码的情况,应该是memset有森马特殊作用,我去查查
寻森良Z
2014-08-21 · TA获得超过368个赞
知道小有建树答主
回答量:124
采纳率:0%
帮助的人:131万
展开全部
权威人士告诉你:
char a[10];
如果此变量前后都不是char或char数组,那么实际上a占用的可用空间并不是10个字节,而是12个字节。这是由于“自动对齐”策略造成的。即这里 char a[10]会被编译器自动调整为 char a[12]。但是a[10]和a[11]的值是“未定”的,它可能是0,也可能不是0。

但是,如果char a[10]的前后定义了其它char变量,很抱歉的告诉你,编译器可能不会延长a的可用空间。届时a[10]已经越界了,C/C++并不做越界检查,即程序运行可以继续,但如果你修改了越界内容,可能造成程序的“未知”行为发生。

举例:
char a[10];
char b = 'b';

a[10] = '\0'; // 实际上是将 b 设置为了'\0'
追问
道理是明白了,但是例子试了下还是不行,还是显示a【10】为空,但是b还是b没有改额。。。在a前面定义b也没有改变b。这是怎么回事呢
追答

原因是编译器对变量的位置进行了重排。

char c;

char a[10];

char b;

被重排后的顺序是:

char c;

char b;

char a[10];

所以这时候a[10]=0不会更改b和c。


在有些系统下,编译器的默认对齐策略不是4字节,而是8字节,这意味着char a[10]实际上占用16个字节。


char a[10] = “String-A”;
char d[10] = "String-D";
a[16] = 0;
printf("d = %s, should be \"String-D\"\n", d);
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
闹闹FCf
2014-08-21 · 超过60用户采纳过TA的回答
知道答主
回答量:122
采纳率:0%
帮助的人:134万
展开全部
同学你好,我也遇到过这样的问题,数组定义时,行列数不能用变量。 但是, 我们可以动态创建一个二维数组。

你可以这样做:(以int型为例)

int **a;
int m,n,i;
scanf("%d%d",&m,&n); //输入你此次想要创建数组的行数和列数,储存在m和n中

a=(int**)malloc(m*sizeof(int*)); /*malloc函数在stdlib.h里面,用的时候加入这个头文件*/

for(i=0;i<m;i++)
a[i]=(int*)malloc(n*sizeof(int));

/*这样以后你就可以把a当作二维数组a[m][n]来用了。。

由此可以实现,创建不确定行列数的二维数组了 ( 前提你知道malloc函数的意义,并要掌握指针的基础知识哦 )
采纳我哟~~
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
kaixingui2012
2014-08-21 · TA获得超过4.2万个赞
知道大有可为答主
回答量:1.4万
采纳率:81%
帮助的人:6432万
展开全部
char a[10]; 有效单元为a[0]-a[9] 能存储的有效数据为a[0]-a[8] a[9]用来存储字符串结束符'\0'
你发现居然分配了a[10]说明你的数据访问越界了,这个不是分配来的,是你的数据超过了9位导致数据越界访问,占用了其他数据的内存,这样是很危险的,很可能会出现程序异常!
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
百度网友e3ce692
2014-08-21 · TA获得超过156个赞
知道小有建树答主
回答量:215
采纳率:100%
帮助的人:191万
展开全部
这么跟你说吧,你定义一个字符串,不管有多少位,都要有一个存储‘\0’的,因为这是结束符,比如你定义a[10],如果你输入了5个数组,即a[0]-a[4],那个a[5]就存储‘\0’,表示你这个字符串结束了,如果没有‘\0’就表示字符串还没有结束,后面还有内容,一般情况下‘\0’是自动加上的,表示你字符串结束,在缺少的情况下puts输出会报错,因为没读到结束符就会一直输出,但是后面又没有值
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
jiangsanhuo
2014-08-21 · TA获得超过169个赞
知道小有建树答主
回答量:291
采纳率:81%
帮助的人:175万
展开全部
a[1000]都有,只是你越界访问破坏了其他的栈变量
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(5)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式