[c 语言或 Linux ] 吐槽加请教,高手请进

2018-11-19 20:01:40 +08:00
 fuchar

最近用 C 在 leetcode 上写了几题,发现当返回二维数组时经常出现 runtime error,或 free()出错,来回检查都没有发现错误,在自己机子上编译也能通过。让我一度以为自己指针没学好,又看了一遍书。

等脑袋清醒一点后再在 leetcode 上测试,终于发现是他主函数的 free()的策略和我的不一样。leetcode 默认我申请空间时方式是用时分配空间 先是 int** returnArry=(int**)malloc(10sizeof(int)),然后需要增加一个数组时再 (int*)malloc(10*sizeof(int))

但是尴尬的是我为了提高效率,第一步一样的,但不是用时分配空间,而是直接分配连续二维数组空间 returnArry[0]=(int*)malloc(1010sizeof(int)) 这就造成了我的结果是对的,但他的主函数 free()时是循环执行 free(returnArry[i++]), 本来我的 malloc 只用了两次,但主函数多次 free,这就造成了我返回的指针成了野指针,害我纠结了很久,真的坑爹。

话说,本来 c 语言的优势就是执行快,但用时分配空间的做法,降低了效率,同样的算法,还不如 Python 快。各位大神有没有绕过这种 leetcode 这种 free 方式的 malloc 的方法,分享一下呗

如果是换种语言。。。。。。就别提了,换个平台还可以考虑,不过我挺喜欢 leetcode 不用关心输入输出格式的

或者像 github 或别的平台上有没有比较适合的开源项目,最好有指导怎么逐步构建的

再多问一点,我最近再看 unix 环境高级编程,差不多看了一大半,上面的代码我照着书也能磕磕绊绊的敲出来,简单的命令也能写,但感觉很虚,没有详细的出错检测,异常处理,我看书后面有 open 服务器构建,我过段时间会写,但现在有没有可以做的东西

求大神指导,拜谢

3432 次点击
所在节点    程序员
11 条回复
Ediacaran
2018-11-19 20:12:16 +08:00
看描述好像是混淆了 指针的数组 和 二维数组 两个概念。
raynor2011
2018-11-19 20:17:26 +08:00
直接贴题目链接和代码吧,一大堆文字太难受了
fuchar
2018-11-19 20:24:11 +08:00
@Ediacaran
可能是我没说清楚,函数要求返回一个 int**的指针。另外这个指针的问题我已经解决了,主要是想问有没有比较好的内存分配方式,既让 leetcode 主函数 free 成功,又可以提升效率,需要加一个数组的时候再用 malloc 分配空间,确实很耗时间
2pang
2018-11-19 20:25:28 +08:00
lz 你代码写错了
你文中的 int** returnArry=(int**)malloc(10sizeof(int)
int*的大小和 int 的大小不一定一样 也许你本地是 32 位 碰巧没出错
fuchar
2018-11-19 20:32:28 +08:00
@2pang 笔误,笔误

https://leetcode.com/problems/3sum/
/**
* Return an array of arrays of size *returnSize.
* Note: The returned array must be malloced, assume caller calls free().
*/
int cmp(int *a, int *b){
return *a - *b;
}

int** threeSum(int* nums, int numsSize, int* returnSize) {
int **sum;
int i, l, r, x, t=0;
sum = (int**)malloc(sizeof(int*)*20000);
/**
*这是我原来的分配方式
* sum[0]=(int*)malloc(sizeof(int)*20000*3);
* for(i=1; i<20000; i++)
* sum[i] = sum[0] + i*3;
qsort(nums, numsSize, sizeof(int), cmp);

for(i=0; i<numsSize-2 && nums[i]<=0 ; i++ ){
if( i>0 && nums[i]==nums[i-1] )
continue;
for(l=i+1, r=numsSize-1; l<r; ){
x= nums[i]+nums[l]+nums[r];
if( x==0 ){
//这是 leetcode 默认的分配方式
sum[t] = (int*)malloc(sizeof(int)*3);
sum[t][0] = nums[i];
sum[t][1] = nums[l];
sum[t][2] = nums[r];
t++;
for(r--; r>l && nums[r]==nums[r+1]; r--)
;
for(l++; l<r && nums[l]==nums[l-1]; l++)
;
}
else if( x>0 )
for(r--;r>l && nums[r]==nums[r+1]; r--)
;
else
for(l++; l<r && nums[l]==nums[l-1]; l++)
;
}
}
*returnSize = t;
return sum;

}
wevsty
2018-11-19 21:53:55 +08:00
基于 C99 标准考虑的话,要动态分配内存有两种办法
1、可变长数组( Variable length array,简称 VLA )。
2、malloc 系列函数。
然而似乎很多编译器不支持 VLA,或者直接把 VLA 用 malloc 实现。
所以从实际结果看,除了 malloc 以外没有什么其他方法动态分配内存。
程序运行慢多半还是楼主自己实现的问题。

* Return an array of arrays of size *returnSize.
* Note: The returned array must be malloced, assume caller calls free().

但是人家题目已经说的很明白了,这算是人家题目的要求,无视要求是无法得到一个正确答案的。
contmonad
2018-11-20 00:25:54 +08:00
没啥简单的办法,他的接口已经设计成这样了。除非你知道 leetcode 用的哪种编译器 / malloc 算法,然后自己 hack 一下把元数据字段填上,骗过 free 调用。但是也不一定可以。
ryd994
2018-11-20 01:33:45 +08:00
不要小看内存分配器
你这种情况,即使是多次分配,很可能还是连续的
iceheart
2018-11-20 06:10:18 +08:00
题目说的不是很清楚了吗?返回指针数组,每个元素用 malloc 分配。
你究竟要搞什么事情?
zwh2698
2018-11-20 06:34:29 +08:00
C 语言是需要修炼的,不是学习可以解决的
jmc891205
2018-11-20 10:07:57 +08:00
别在 leetcode 上 换个其他的用文本做输入输出的 OJ 刷题
自己负责 free 就没这个问题了

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

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

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

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

© 2021 V2EX