memset 和 二维数组之间个“隔阂”

版权声明:如果是原创仅供参考,转请标明出处。 https://blog.csdn.net/oShuaiFeng/article/details/80709726

前言:今天在做的题目之中 出现了一个十分有趣的现象 就是 使用memset中直接的问题。现在分享一下。


掉坑的题目 《1050 螺旋矩阵(25)(25 分)》


我们定义二维数组不过是三种方法 

1.直接定义法   int P[100][100];

2.malloc定义法 int** P = (int **)malloc(sizeof(int *)*100); for(int i=0;i<100;i++) P[i]=(int *)malloc(sizeof(int)*100);

3.calloc 定义法 int** P = (int **)calloc(100,sizeof(int *)); for(int i=0;i<100;i++) P[i]=(int *)calloc(100,sizeof(int));


有的人说了 malloc不是大致和calloc相同吗? 但是有时候 一些细节就会让你 好久都没有办法查的出来。比如我今天所说的memset的超级大坑。


扫描二维码关注公众号,回复: 4020177 查看本文章

为了掉进我设下的这个坑 我们 使用方法 2 开辟了空间 创建了二维数组 。我们知道 使用malloc开辟的二维数组每一个元素的值就像在局部变量一样都是随机值。 

这个时候 心大的同学就很想 使用 memset 来初始化这个“数组”了 在我们的印象里 我们初始化 使用 方法 1 定义的数组的时候都是这样的 (例如初始化为 0 ):memset(P,0,sizeof(P));

	int P[100][100];
	memset(P, 0, sizeof(P));

执行完成以后 通过编译器的调试框 我们可以看出 是初始化成功了

初始化前:


初始化后:


显然是成功的。


但是 但是 但是 。 我们使用方法 2 定义的“数组”再使用 这个方法的 话 就会掉进万丈深坑 !我们来看图

因为 不是 标准定义的数组 我们没法像上面这样直观的 表现出来 我们取 局部的图 来说明问题的所在。

因为只要开辟成功 那么 我读 P[0][0] 是不是应该是一个随机值。 对,我就要它读出随机值的图来分析 。


这个 就是执行memset之前的 P[0][0] 的情况 我们看到了 随机值。 

然后我万恶的点击了单步。

结果就是这样的 


WTF 读不出来了  但是 P[1][0]却能读出来 而且 并没有初始化 如图:


没有初始化我就不怪你了 还让我读不出来 ~~~ 什么破编译器 炸了算了。

但是我没有炸 我 把 P[0]和 NULL 做了一个比较


注意看我单步的黄色光标 我单步了哦 别看走眼


NULL NULL 我发现了什么  我发现了是 NULL 耶!从此学了一个新词  NULL 来 NULL 去 欢迎广大读友用来造句。哈哈

这样所有的谜题就解开了? 没有,因为 P[1]!=NULL 那这个又是怎么回事呢? 

我们把目光投向那个 sizeof(P) 这里 按照我们正常的思维 我们猜一下 这个运算的结果是什么?答案是 4 !!

诶 我不是开了100的那个二维指针空间了吗?咋就是 4 了????而且这100个空间都是连续的啊!!

有些稀里糊涂的人马上就站出来 理直气壮的说 这个就是 4 没错啊,就同一般定义的二维数组一样啊 。不一样 我们看

是不是 4万 ??????? 说明了一般的数组是可以计算出数组 "连续" 空间的大小的 因为整数型 int 一个空间的大小是 4 ,100行100列一共有 100*100 == 10000个元素  所以 10000*4 == 40000 。

四...四万是么?刚刚看错了,对啊 就是 4万啊 。(你给我粗去~~马上立刻~ )

那么为什么 是 4 呢? 有的人又说了 那有可能是 sizeof(a[0]) ; 不对了啊~ 这个是 400 就不附图了 截图浪费时间啊


那么 4 从哪来 它又要到哪里去呢?????????? 总不能让他 NULL来NULL去吧!

然后我就试了一下这一组:



我们想一下 刚刚的P是不是一个二维的指针 那么这个4 是不是就是那个4了?

我回去看了一下 P的定义


啊~~~我尖叫了出来,手里的辣条 都忘记了 。

这这这这 ,这不是 变 变量吗  我不敢相信我的眼睛 于是我做了一个测试。

 

这下问题就彻底的暴露出来了

正经的解释开始:

1.P 无论怎样给它开空间 说到头 它就是一个变量 一个二维指针的变量,所以 用它计算空间的值自然就是 sizeof(空间的类型);

也就等同于sizeof(int**) 这个实验我们上面已经做过了 答案是 4 

2.所以 我们 完全的了解了。


那么我们怎么解决初始化的问题呢  不会有是两个for吧 不是的啦 怎么这么 “土”呢?

我们还记得 calloc吗 用它来开辟的二维数组的空间默认就是初始化为 0 了呗 。

我们看下图 



解决初始化问题。而且  嘿嘿~~


没有执行 if 它不再是一个NULL来NULL去的指针了~~


解决问题了。


忘记几个人真的好难啊!我好想回到大学以前 可是 又不能多想 因为现在自己的命运捏在自己手上,即使受伤也要 前进。

猜你喜欢

转载自blog.csdn.net/oShuaiFeng/article/details/80709726