[爆卦]malloc二維陣列是什麼?優點缺點精華區懶人包

為什麼這篇malloc二維陣列鄉民發文收入到精華區:因為在malloc二維陣列這個討論話題中,有許多相關的文章在討論,這篇最有參考價值!作者DirKai (Dirk_AI(MIX))看板C_and_CPP標題[問題] 二維陣列 指標傳遞...


開發平台(Platform): (Ex: Win10, Linux, ...)
win 7

編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出)
code blocks

額外使用到的函數庫(Library Used): (Ex: OpenGL, ...)


問題(Question):

兩種情況,第一種正常,第二種有問題,不懂為什麼。

1.
void test(unsigned char img[640][480])
{
unsigned char *img_r; //用一維指標接二維陣列(不懂目的,有甚麼好處嗎?)

imgr = &img[0][0];


執行運算..

}

main()
{
unsigned char img[640][480];

...

test(img);

}


2. 其實這是我改的,compile出錯,有時卻會順利執行到結束

void test(unsigned char **img)
{
unsigned char *img_r; //用一維指標接二維陣列(不懂目的,有甚麼好處嗎?)

img_r = img;


執行運算..

}

main()
{
unsigned char **img;
unsigned long i;

img=(unsigned char**)malloc(512*sizeof(unsigned char*));

for(i=0; i<512; i++)
img[i]=(unsigned char*)malloc(640*sizeof(unsigned char));


test(img);

}

餵入的資料(Input):

image raw data


預期的正確結果(Expected Output):


我是不知道為何原本的程式要把二維位址傳到一維,

但不論目的,我覺得我改這樣跟原本沒甚麼差吧?

除了在記憶體內 可能排列不太一樣之外(?

錯誤結果(Wrong Output):


有時程式執行到一半直接當掉,檢查是在test副程式內運算一維陣列時出錯


程式碼(Code):(請善用置底文網頁, 記得排版)


補充說明(Supplement):



1.我不知道為何要丟給一維去處理,這樣有甚麼好處嗎? 比較快?

(那乾脆讀圖就用一維接阿@@?)


2.我這兩種寫法有甚麼具體的差別嗎? 我是不是想錯甚麼了?






--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 118.163.54.15
※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1478655008.A.D1A.html
theTai: 感覺好像是置底十三戒中的第十二條 11/09 09:36

謝謝,我等等看一下

steve1012: 你用一個pointer 接double pointer 不覺得怪嗎 11/09 09:39
steve1012: 都不用derefernce? 11/09 09:40

1不是我寫的阿,所以文中我有說,我也不知道為什麼,也不懂目的...

pttworld: 2之test不就直接拿二維的img運算了。 11/09 09:49

我也覺得...可是目前程式碼就是硬要丟到一維,我不確定目的之前還不想改他

因為目前是沒有bug狀態
※ 編輯: DirKai (118.163.54.15), 11/09/2016 09:54:12
pttworld: 實務上怕動到可以新寫函數內容小改,要註解捨棄也容易。 11/09 10:10
pttworld: 業界的話因為有版控,改錯了抓history回來覆蓋程式段。 11/09 10:11
aiwhat: 1裡面資料都是連續,2裡面不一定連續吧? 11/09 12:17
aiwhat: 後面的運算如果是把它當成640*480大小的array感覺會炸掉 11/09 12:18
aiwhat: for i = [0, 640*480) do img_r[i] = xxx; end-for 這種 11/09 12:20



其實我主要是想問,2到底做錯了甚麼,為什麼1程式執行正常,

2.的程式執行會當掉?


我自己之前寫的img都是二維動態陣列,讀很大的圖檔也都沒事


可是,現在傳給一維就出錯,是因為連不連續的問題嗎?
※ 編輯: DirKai (118.163.54.15), 11/09/2016 13:36:03
steve1012: 一的type 是對的 11/09 13:53
steve1012: 2 根本連compile都不會過 你怎麼讓他跑的? 11/09 13:59
steve1012: 2 你用一個pointer接double start pointer 光type就錯 11/09 13:59
steve1012: 怎麼會對? 11/09 14:00


所以1.的 img[512][640]傳過去 test(img); 是算pointer 非double pointer嗎?


2.我的確compile過耶...到執行階段程式才當掉。


※ 編輯: DirKai (118.163.54.15), 11/09/2016 14:03:34
steve1012: 我上面的推文本來就是講2 1本來就沒有錯 11/09 14:01
steve1012: 寫code有時候為了乾淨 的確可能會把一個2d array的每一 11/09 14:02
steve1012: 個row 都特別用一個pointer去指 看起來比較乾淨 11/09 14:02
steve1012: 不過你給的code片段太少 很難知道為啥他要這樣 11/09 14:02
steve1012: 但1本來就沒錯就是了 11/09 14:03


了解 謝謝steve,我上面誤會你的推文了,抱歉。

程式碼的確常常用一維的array去指2d array,

然後一維的pointer 一直加陣列寬去找自己要的column,


這樣對於執行速度有比較快嗎? 還是只是為了整齊??

因為我個人覺得反而難閱讀就是了啦(也可能單純我菜@@)


想特別請教一下steve

1.的 img[512][640]傳過去 test(img); 是算pointer 非double pointer嗎?

※ 編輯: DirKai (118.163.54.15), 11/09/2016 14:10:31
steve1012: 不是 img[0][0] 是第一個element &img[0][0]是它的位 11/09 14:17
steve1012: 置 跟 *img 指導的地方基本上一樣 11/09 14:19


那如果我用2.的方式改成 img_r = &img[0][0]; 會有甚麼問題嗎?

這樣子改也是給他一個位址,只是資料不連續。
※ 編輯: DirKai (118.163.54.15), 11/09/2016 14:26:15
aiwhat: 2的後續運算有img_r[i * width + j]這種東西嗎? 11/09 14:28


算有,原程式碼都是又宣告另外的一維指標

unsigned char *img1, *img2....;

img1 = img_r + width;
img2 = img1 + width;

...

然後對 img1[N]、img2[N] 去做運算 N=0 ~ width-1

應該就是你寫的那樣。 所以有你推文寫的那個,


aiwhat: 照main裡面的配置方式應該超過640就會越界了吧 11/09 14:29
aiwhat: 而且 main 裡面的 for 應該是 i = [0, 512)不是[0, 640) 11/09 14:31

對 那個for我打錯了,我程式裡面沒打錯,抱歉>"<
※ 編輯: DirKai (118.163.54.15), 11/09/2016 14:36:12
aiwhat: 但是你main裡面那樣配置 img2 = img1 + width可能會越界 11/09 14:48
aiwhat: &img[0] + width == &img[1] 結果應該會是 false 11/09 14:51


為什麼?? ai大是指2.的寫法嗎? 還是兩種都會?

越界是指動態陣列不連續 所以會越界嗎
※ 編輯: DirKai (118.163.54.15), 11/09/2016 14:54:52
aiwhat: img[i]裡面只保證img[i][0~639]是連續 11/09 14:56
aiwhat: img[i][639]→img[i+1][0]不一定連續 11/09 14:57
aiwhat: 我是指2的寫法 11/09 15:01

了解,所以是記憶體配置的問題。 如果不要用這種寫法應該就ok

謝謝以上替我解答的各位。

※ 編輯: DirKai (118.163.54.15), 11/09/2016 15:31:11
aiwhat: 14:51那個寫錯 (&img[0][0] + width == &img[1][0]) 11/09 16:57

你可能也想看看

搜尋相關網站