本地能运行的C程序,为什么在LeetCode上会失败?

在做LeetCode第22题时,https://leetcode-cn.com/problems/generate-parentheses/

我一开始写了下面这些代码

void generateOneByOne(char *sublist, char ***result, int left, int right, int index, int* returnSize)
{
    //终止条件,使用完所有的括号
    if (left == 0 && right == 0){
        int new_size = *returnSize + 1;
        //如果原来为空
        if ( *result == NULL ) {
            *result = (char **)malloc( sizeof(char*) *  new_size);
        } else{
            //如果不为空,则要重新分配下内存
            *result = (char **)realloc(*result, new_size * sizeof(char *));
        }
        //增加新的数据
        (*result)[*returnSize] = (char *)malloc( sizeof(char) * strlen(sublist) );
        strcpy((*result)[*returnSize], sublist);
        *returnSize = new_size;
    }
    if ( left > 0){
        sublist[index] = '(';
        index++;
        generateOneByOne(sublist, result, left - 1, right, index, returnSize);
        //恢复现场
        index--;

    }
    if ( right > left){
        sublist[index] = ')';
        index++;
        generateOneByOne(sublist, result, left, right - 1, index, returnSize);
        index--;

    }

}
//result, 一开始**result
char ** generateParenthesis(int n, int* returnSize){
    int str_len = n * 2 + 1;
    char *substring = (char *)malloc(sizeof(char) * str_len);
    substring[str_len] = '\0';
    char **result = NULL;
    generateOneByOne(substring, &result, n, n,0, returnSize);
    return result;

}

在本地运行的时候,是没有任何问题,而在LeetCode上运行时, 就报错了,

=================================================================
==29==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000014 at pc 0x000000401d79 bp 0x7ffe252ab3d0 sp 0x7ffe252ab3c8
WRITE of size 1 at 0x602000000014 thread T0
    #2 0x7f36d55b22e0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202e0)
0x602000000014 is located 0 bytes to the right of 4-byte region [0x602000000010,0x602000000014)
allocated by thread T0 here:
    #0 0x7f36d6e612b0 in malloc (/usr/local/lib64/libasan.so.5+0xe82b0)
    #3 0x7f36d55b22e0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202e0)
Shadow bytes around the buggy address:
  0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000: fa fa[04]fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==29==ABORTING

错误太长,而且我也看不懂。于是我按照我的经验,检索了" AddressSanitizer: heap-buffer-overflow "相关内容,一个可靠回答在https://stackoverflow.com/questions/51579267/addresssanitizer-heap-buffer-overflow-on-address

简单都说,就是通常的C编译器是不会检查边界问题的,也就是如果我定义了int a[10],我访问a[100]也不会提示错误。但是,如果你在编译的时候加上-fsanitize=address参数,程序运行的时候就会做边界检查,在越界的时候报错。

因此我的源代码中存在了我没有发现的越界行为,你能看出是哪里吗?

第一处是substring[str_len] = '\0', 大小为N的数组,最后一位是N-1。

第二处错误在(*result)[*returnSize] = (char *)malloc( sizeof(char) * strlen(sublist) );中,新申请的内存大小应该是sizeof(char) * (strlen(sublist) + 1), 需要放在最后的'\0';

此外,对于这种“明明我可以”的报错,官方建议你绕行C/C++,换个编程语言

C/C++
The most frequent culprit causing undefined behavior is out-of-bounds array access. These bugs could be hard to debug, so good luck. Or just give up on C/C++ entirely and code in a more predictable language, like Java. :)

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值