最近用 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 20:12:16 +08:00
看描述好像是混淆了 指针的数组 和 二维数组 两个概念。
|
2
raynor2011 2018-11-19 20:17:26 +08:00 1
直接贴题目链接和代码吧,一大堆文字太难受了
|
3
fuchar OP @Ediacaran
可能是我没说清楚,函数要求返回一个 int**的指针。另外这个指针的问题我已经解决了,主要是想问有没有比较好的内存分配方式,既让 leetcode 主函数 free 成功,又可以提升效率,需要加一个数组的时候再用 malloc 分配空间,确实很耗时间 |
4
2pang 2018-11-19 20:25:28 +08:00 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 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(). 但是人家题目已经说的很明白了,这算是人家题目的要求,无视要求是无法得到一个正确答案的。 |
7
contmonad 2018-11-20 00:25:54 +08:00
没啥简单的办法,他的接口已经设计成这样了。除非你知道 leetcode 用的哪种编译器 / malloc 算法,然后自己 hack 一下把元数据字段填上,骗过 free 调用。但是也不一定可以。
|
8
ryd994 2018-11-20 01:33:45 +08:00 via iPhone
不要小看内存分配器
你这种情况,即使是多次分配,很可能还是连续的 |
9
iceheart 2018-11-20 06:10:18 +08:00 via Android
题目说的不是很清楚了吗?返回指针数组,每个元素用 malloc 分配。
你究竟要搞什么事情? |
10
zwh2698 2018-11-20 06:34:29 +08:00 via Android
C 语言是需要修炼的,不是学习可以解决的
|
11
jmc891205 2018-11-20 10:07:57 +08:00
别在 leetcode 上 换个其他的用文本做输入输出的 OJ 刷题
自己负责 free 就没这个问题了 |