V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
fuchar
V2EX  ›  程序员

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

  •  
  •   fuchar · 2018-11-19 20:01:40 +08:00 · 3264 次点击
    这是一个创建于 1977 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近用 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 服务器构建,我过段时间会写,但现在有没有可以做的东西

    求大神指导,拜谢

    第 1 条附言  ·  2018-11-19 20:34:50 +08:00

    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)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;

    }

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

    但是人家题目已经说的很明白了,这算是人家题目的要求,无视要求是无法得到一个正确答案的。
    contmonad
        7
    contmonad  
       2018-11-20 00:25:54 +08:00
    没啥简单的办法,他的接口已经设计成这样了。除非你知道 leetcode 用的哪种编译器 / malloc 算法,然后自己 hack 一下把元数据字段填上,骗过 free 调用。但是也不一定可以。
    ryd994
        8
    ryd994  
       2018-11-20 01:33:45 +08:00 via iPhone
    不要小看内存分配器
    你这种情况,即使是多次分配,很可能还是连续的
    iceheart
        9
    iceheart  
       2018-11-20 06:10:18 +08:00 via Android
    题目说的不是很清楚了吗?返回指针数组,每个元素用 malloc 分配。
    你究竟要搞什么事情?
    zwh2698
        10
    zwh2698  
       2018-11-20 06:34:29 +08:00 via Android
    C 语言是需要修炼的,不是学习可以解决的
    jmc891205
        11
    jmc891205  
       2018-11-20 10:07:57 +08:00
    别在 leetcode 上 换个其他的用文本做输入输出的 OJ 刷题
    自己负责 free 就没这个问题了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2824 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 11:29 · PVG 19:29 · LAX 04:29 · JFK 07:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.