作者DirKai (Dirk_AI(MIX))
看板C_and_CPP
标题[问题] 二维阵列 指标传递
时间Wed Nov 9 09:30:05 2016
开发平台(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://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1478655008.A.D1A.html
1F:→ theTai: 感觉好像是置底十三戒中的第十二条 11/09 09:36
谢谢,我等等看一下
2F:推 steve1012: 你用一个pointer 接double pointer 不觉得怪吗 11/09 09:39
3F:→ steve1012: 都不用derefernce? 11/09 09:40
1不是我写的阿,所以文中我有说,我也不知道为什麽,也不懂目的...
4F:→ pttworld: 2之test不就直接拿二维的img运算了。 11/09 09:49
我也觉得...可是目前程式码就是硬要丢到一维,我不确定目的之前还不想改他
因为目前是没有bug状态
※ 编辑: DirKai (118.163.54.15), 11/09/2016 09:54:12
5F:→ pttworld: 实务上怕动到可以新写函数内容小改,要注解舍弃也容易。 11/09 10:10
6F:→ pttworld: 业界的话因为有版控,改错了抓history回来覆盖程式段。 11/09 10:11
7F:→ aiwhat: 1里面资料都是连续,2里面不一定连续吧? 11/09 12:17
8F:→ aiwhat: 後面的运算如果是把它当成640*480大小的array感觉会炸掉 11/09 12:18
9F:→ 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
10F:推 steve1012: 一的type 是对的 11/09 13:53
11F:推 steve1012: 2 根本连compile都不会过 你怎麽让他跑的? 11/09 13:59
12F:→ steve1012: 2 你用一个pointer接double start pointer 光type就错 11/09 13:59
13F:→ 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
14F:→ steve1012: 我上面的推文本来就是讲2 1本来就没有错 11/09 14:01
15F:→ steve1012: 写code有时候为了乾净 的确可能会把一个2d array的每一 11/09 14:02
16F:→ steve1012: 个row 都特别用一个pointer去指 看起来比较乾净 11/09 14:02
17F:→ steve1012: 不过你给的code片段太少 很难知道为啥他要这样 11/09 14:02
18F:→ 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
19F:推 steve1012: 不是 img[0][0] 是第一个element &img[0][0]是它的位 11/09 14:17
20F:推 steve1012: 置 跟 *img 指导的地方基本上一样 11/09 14:19
那如果我用2.的方式改成 img_r = &img[0][0]; 会有甚麽问题吗?
这样子改也是给他一个位址,只是资料不连续。
※ 编辑: DirKai (118.163.54.15), 11/09/2016 14:26:15
21F:→ 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
应该就是你写的那样。 所以有你推文写的那个,
22F:→ aiwhat: 照main里面的配置方式应该超过640就会越界了吧 11/09 14:29
23F:→ aiwhat: 而且 main 里面的 for 应该是 i = [0, 512)不是[0, 640) 11/09 14:31
对 那个for我打错了,我程式里面没打错,抱歉>"<
※ 编辑: DirKai (118.163.54.15), 11/09/2016 14:36:12
24F:→ aiwhat: 但是你main里面那样配置 img2 = img1 + width可能会越界 11/09 14:48
25F:→ aiwhat: &img[0] + width == &img[1] 结果应该会是 false 11/09 14:51
为什麽?? ai大是指2.的写法吗? 还是两种都会?
越界是指动态阵列不连续 所以会越界吗
※ 编辑: DirKai (118.163.54.15), 11/09/2016 14:54:52
26F:→ aiwhat: img[i]里面只保证img[i][0~639]是连续 11/09 14:56
27F:→ aiwhat: img[i][639]→img[i+1][0]不一定连续 11/09 14:57
28F:→ aiwhat: 我是指2的写法 11/09 15:01
了解,所以是记忆体配置的问题。 如果不要用这种写法应该就ok
谢谢以上替我解答的各位。
※ 编辑: DirKai (118.163.54.15), 11/09/2016 15:31:11
29F:→ aiwhat: 14:51那个写错 (&img[0][0] + width == &img[1][0]) 11/09 16:57