1. 程式人生 > >memset 和 二維陣列之間個“隔閡”

memset 和 二維陣列之間個“隔閡”

前言:今天在做的題目之中 出現了一個十分有趣的現象 就是 使用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的超級大坑。


為了掉進我設下的這個坑 我們 使用方法 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去的指標了~~


解決問題了。


忘記幾個人真的好難啊!我好想回到大學以前 可是 又不能多想 因為現在自己的命運捏在自己手上,即使受傷也要 前進。