
最近用 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 服务器构建,我过段时间会写,但现在有没有可以做的东西
求大神指导,拜谢
https://leetcode.com/problems/3sum/ /**
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)200003); * 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;
}
1 Ediacaran 2018 年 11 月 19 日 看描述好像是混淆了 指针的数组 和 二维数组 两个概念。 |
2 raynor2011 2018 年 11 月 19 日 直接贴题目链接和代码吧,一大堆文字太难受了 |
3 fuchar OP @Ediacaran 可能是我没说清楚,函数要求返回一个 int**的指针。另外这个指针的问题我已经解决了,主要是想问有没有比较好的内存分配方式,既让 leetcode 主函数 free 成功,又可以提升效率,需要加一个数组的时候再用 malloc 分配空间,确实很耗时间 |
4 2pang 2018 年 11 月 19 日 via iPhone lz 你代码写错了 你文中的 int** returnArry=(int**)malloc(10sizeof(int) int*的大小和 int 的大小不一定一样 也许你本地是 32 位 碰巧没出错 |
5 fuchar OP @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; } |
6 wevsty 2018 年 11 月 19 日 基于 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(). 但是人家题目已经说的很明白了,这算是人家题目的要求,无视要求是无法得到一个正确答案的。 |
7 contmonad 2018 年 11 月 20 日 没啥简单的办法,他的接口已经设计成这样了。除非你知道 leetcode 用的哪种编译器 / malloc 算法,然后自己 hack 一下把元数据字段填上,骗过 free 调用。但是也不一定可以。 |
8 ryd994 2018 年 11 月 20 日 via iPhone 不要小看内存分配器 你这种情况,即使是多次分配,很可能还是连续的 |
9 iceheart 2018 年 11 月 20 日 via Android 题目说的不是很清楚了吗?返回指针数组,每个元素用 malloc 分配。 你究竟要搞什么事情? |
10 zwh2698 2018 年 11 月 20 日 via Android C 语言是需要修炼的,不是学习可以解决的 |
11 jmc891205 2018 年 11 月 20 日 别在 leetcode 上 换个其他的用文本做输入输出的 OJ 刷题 自己负责 free 就没这个问题了 |