二维数组的内存分配及访问

以下内容适合X86平台大端模式,小端模式没有验证。
1.
int n,m;
cin>>n>>m;
int dp[n][m];
dp数组的内存在栈区,内存大小在编译时能确认吗?当声明为int dp[4][4],dp内存在编译时确认,在栈区静态分配。维度存在变量时,
在栈区动态分配。(动态分配的内存并不是都在堆区,C提供了在栈中动态分配内存的函数alloca,用法和malloc一样,但不用free,
因为他是在栈中分配空间,超出定义域后自动释放)。dp的内存大小为动态分配内存时的nm4byte。
2.
int n=6,m=6;
int dp[n][m];
dp数组的内存在栈区,占用的内存是确定的dp到dp+nm4byte(后续修改n,m值无影响)。dp[i][j]的地址为dp+(im+j)4。
c++不做越界检查(i,j可为负值)。当i>5,j>5或为负数时,若地址对应内存未被占用,实际上是可访问的,若有保护权限,
相应的操作会触发段错误Segmentation fault (core dumped)。
3.
当n,m没有初始化会出现什么情况呢?
int n,m;
int dp[n][m];
事实上,n,m会存在一个随机值,此时情况就与1相同了。n,m的随机值可能很大,占用大量的栈区资源。
另外n,m也可能为负数,形如int dp[-2][-4]的声明是错误的,编译时会报错:array的size为负,那么如下声明会出现什么情况呢?
int n=-2,m=-4;
int dp[n][m];
n,m同时为负数时,编译是可以通过的,占用的内存是确定的dp到dp+n
m
4byte,dp[i][j]的地址依然为dp+(i*m+j)*4,(这是由动态分
配带来的特性),其实际占用的内存范围也为计算出来的地址范围,正常访问将与n,m为负数时对应的i,j取正值即可。n,m不同时为负数时,
动态分配就不可行了,会触发段错误Segmentation fault (core dumped)。n,m一个为0时,动态分配的内存大小也为0。
(安全性未严格验证,正确性存疑,不推荐使用,就不细究了)。

总结:使用未初始化的变量去声明数组,可能编译及运行过程正常,实则存在资源浪费或非法访问的隐患。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值