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

您所在的位置:网站首页 c语言在电脑上怎么运行的 本地能运行的C程序,为什么在LeetCode上会失败?

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

2024-03-24 01:00| 来源: 网络整理| 查看: 265

在做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. :)



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3