二重指针申请和释放空间的正确姿势(C/C++)

2015-06-20 19:10:23 +08:00
 tianshilei1992

现在想申请一个 h × w 的二维矩阵,用二重指针来表示,申请的代码有两种,如下:
代码1:
float allocf(int h, int w) {
float **p = (float
)malloc(sizeof(float) * h);
if (!p) {
cerr << "Memory Allocation Error!" << endl;
exit(1);
}
for (int i = 0; i < h; ++i) {
p[i] = (float
)malloc(sizeof(float) * w);
if (!p[i]) {
cerr << "Memory Allocation Error!" << endl;
exit(1);
}
}
return p;
}
代码2:
int alloci(int h, int w) {
int a = (int)malloc(h * w * sizeof(int));
if (!a) {
cout << "allocu fail." << endl;
exit(0);
}
int **p = (int
)malloc(h * sizeof(int*));
for (int i = 0; i < h; ++i) {
p[i] = &a[i * w];
}
return p;
}
不要在意类型不同,仅仅是示意~~
显然,释放空间的代码也不同:第一种分配方法需要写一个循环来释放空间,而第二种只需要两条 free 语句即可。
那么问题来了,这两种方法哪种比较安全?至于效率上的差距,我想很显然第二种的效率比第一种要好。

2699 次点击
所在节点    C
34 条回复
thinkIn
2015-06-20 19:41:32 +08:00
(float)malloc (int)malloc 什么鬼?
rshun
2015-06-20 19:56:26 +08:00
你的第一段代码如果在第2次内存分配错误之后,就直接exit了,没有free.
而且是c++的语法,为什么要用malloc,不用new?
zwy100e72
2015-06-20 20:10:31 +08:00
大二学生试着回答一下:
第一种方法申请到的是:
指针数组,每个指针单独指向一个数组
第二种方法申请到的是:
指针数组,指针即为楼主要存储的值
zwy100e72
2015-06-20 20:16:58 +08:00
@zwy100e72 补充:
第二种办法使用了索引的方法。。。
指针和对应值不是一起申请的,
值使用的是一维向量的方式存储的,在逻辑上划分为二维矩阵
指针指向逻辑上的首地址

ps: 忘了在什么地方看到的:如果没有释放资源直接退出的话,系统会主动回收资源(但是要长期运行的程序必须注意主动释放
firemiles
2015-06-20 20:30:35 +08:00
@zwy100e72 进程控制块会记录申请的资源,进程退出就会释放资源。
secondwtq
2015-06-20 20:36:07 +08:00
@thinkIn 这是 Markdown 的锅...
tianshilei1992
2015-06-20 21:32:32 +08:00
@rshun 感谢。
程序结束了以后不会自动释放所有分配的资源吗?
tianshilei1992
2015-06-20 21:35:32 +08:00
@thinkIn 唔,估计是 MarkDown 的问题,程序是带指针的。
代码1:

代码2:
tianshilei1992
2015-06-20 21:37:17 +08:00
@zwy100e72 是的,那从安全的角度考虑,二者都一样?效率的话,显然是第二种写法更高效。
tianshilei1992
2015-06-20 21:43:05 +08:00
@rshun 对于非用户自定义类型,new 和 malloc 应该都差不多吧。
28hua
2015-06-20 22:06:12 +08:00
int (*p) [w] = (int (*)[w])malloc(sizeof(int) * h * w);

p[i][j]...

free(p);

这样呢?
czheo
2015-06-20 22:27:06 +08:00
做涉及矩阵变换的时候,2就比1容易得多了。
lsmgeb89
2015-06-20 22:58:39 +08:00
想起了大一的 C 语言作业哈。

感觉第二种写法的 p 很多余啊,你直接用 a 访问就好啦,把一维当作二维用啊,要 p 干嘛。

至于安全嘛,不懂。有书专门讨论 C 的安全写法,参考

http://book.douban.com/subject/4149534/
tianshilei1992
2015-06-20 23:12:53 +08:00
@czheo 因为内存空间是连续的?
tianshilei1992
2015-06-20 23:15:02 +08:00
@lsmgeb89 那样写起来很麻烦的,因为操作矩阵每次都要写 a*w+x
lsmgeb89
2015-06-20 23:18:21 +08:00
@tianshilei1992 其实这点麻烦还算可以接受的啦~~
canautumn
2015-06-20 23:23:04 +08:00
没什么安全不安全的,记着free就行了。说实在的C++那么多安全有用的工具放着不用还用这种低级的语法本身就不安全。如果只是C语言作业练习当我没说。
tianshilei1992
2015-06-21 00:29:41 +08:00
@canautumn 咦?用 C++ 来声明一个 w*h 的 int 类型二维数组怎么声明?
billwsy
2015-06-21 00:37:46 +08:00
@tianshilei1992 vector of vector? 如果很注重效率的话我倾向于写个类然后重载[]函数
zwy100e72
2015-06-21 01:15:52 +08:00
@tianshilei1992 裸指针/数组没有安全性可言。。。别有用心的人构造一个传入参数很有可能就返回了不该返回的东西。。推荐还是用类来实现相关的操作
从效率上讲,完全连续的空间效率最高,可以利用prefecher预取到cpu cache中,这个角度的话是一维数组模拟二维效率最高(使用类进行包装后,相关的函数可以成为内联函数,兼顾效率和安全性)
学识粗浅。。各位随便看看(摊手

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/200062

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX