C语言定义数组问题
vc++中,我定义了chara【10】,按理说是不是应该有啊a【0】-a【9】是个单元哪,但是我调试的时候发现居然分配了a【10】,而且这个单元有时候还可以用,用来存最后...
vc++中,我定义了char a【10】,按理说是不是应该有啊a【0】-a【9】是个单元哪,但是我调试的时候发现居然分配了a【10】,而且这个单元有时候还可以用,用来存最后的一个\0。本人菜鸟,但是很喜欢扣细节,大家谁有相关经验来说说吧,学习一下
展开
7个回答
展开全部
你这种抠细节的精神很好,我来告诉你正确答案。
如果你是定义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黑客最常用的攻击手段。
上面的回复你认真揣摩,希望能对你有用
如果你是定义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有森马特殊作用,我去查查
展开全部
权威人士告诉你:
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'
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);
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
同学你好,我也遇到过这样的问题,数组定义时,行列数不能用变量。 但是, 我们可以动态创建一个二维数组。
你可以这样做:(以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函数的意义,并要掌握指针的基础知识哦 )
采纳我哟~~
你可以这样做:(以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函数的意义,并要掌握指针的基础知识哦 )
采纳我哟~~
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
char a[10]; 有效单元为a[0]-a[9] 能存储的有效数据为a[0]-a[8] a[9]用来存储字符串结束符'\0'
你发现居然分配了a[10]说明你的数据访问越界了,这个不是分配来的,是你的数据超过了9位导致数据越界访问,占用了其他数据的内存,这样是很危险的,很可能会出现程序异常!
你发现居然分配了a[10]说明你的数据访问越界了,这个不是分配来的,是你的数据超过了9位导致数据越界访问,占用了其他数据的内存,这样是很危险的,很可能会出现程序异常!
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
这么跟你说吧,你定义一个字符串,不管有多少位,都要有一个存储‘\0’的,因为这是结束符,比如你定义a[10],如果你输入了5个数组,即a[0]-a[4],那个a[5]就存储‘\0’,表示你这个字符串结束了,如果没有‘\0’就表示字符串还没有结束,后面还有内容,一般情况下‘\0’是自动加上的,表示你字符串结束,在缺少的情况下puts输出会报错,因为没读到结束符就会一直输出,但是后面又没有值
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
a[1000]都有,只是你越界访问破坏了其他的栈变量
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询