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

2024-06-23 20:08

本文主要是介绍本地能运行的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 000x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 000x0c047fff7ff0: 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 fa0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa0x0c047fff8050: 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:           00Partially addressable: 01 02 03 04 05 06 07 Heap left redzone:       faFreed heap region:       fdStack left redzone:      f1Stack mid redzone:       f2Stack right redzone:     f3Stack after return:      f5Stack use after scope:   f8Global redzone:          f9Global init order:       f6Poisoned by user:        f7Container overflow:      fcArray cookie:            acIntra object redzone:    bbASan internal:           feLeft alloca redzone:     caRight 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. :)

这篇关于本地能运行的C程序,为什么在LeetCode上会失败?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1088151

相关文章

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

使用Docker构建Python Flask程序的详细教程

《使用Docker构建PythonFlask程序的详细教程》在当今的软件开发领域,容器化技术正变得越来越流行,而Docker无疑是其中的佼佼者,本文我们就来聊聊如何使用Docker构建一个简单的Py... 目录引言一、准备工作二、创建 Flask 应用程序三、创建 dockerfile四、构建 Docker

一文详解Git中分支本地和远程删除的方法

《一文详解Git中分支本地和远程删除的方法》在使用Git进行版本控制的过程中,我们会创建多个分支来进行不同功能的开发,这就容易涉及到如何正确地删除本地分支和远程分支,下面我们就来看看相关的实现方法吧... 目录技术背景实现步骤删除本地分支删除远程www.chinasem.cn分支同步删除信息到其他机器示例步骤

前端如何通过nginx访问本地端口

《前端如何通过nginx访问本地端口》:本文主要介绍前端如何通过nginx访问本地端口的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、nginx安装1、下载(1)下载地址(2)系统选择(3)版本选择2、安装部署(1)解压(2)配置文件修改(3)启动(4)

k8s上运行的mysql、mariadb数据库的备份记录(支持x86和arm两种架构)

《k8s上运行的mysql、mariadb数据库的备份记录(支持x86和arm两种架构)》本文记录在K8s上运行的MySQL/MariaDB备份方案,通过工具容器执行mysqldump,结合定时任务实... 目录前言一、获取需要备份的数据库的信息二、备份步骤1.准备工作(X86)1.准备工作(arm)2.手

Java使用HttpClient实现图片下载与本地保存功能

《Java使用HttpClient实现图片下载与本地保存功能》在当今数字化时代,网络资源的获取与处理已成为软件开发中的常见需求,其中,图片作为网络上最常见的资源之一,其下载与保存功能在许多应用场景中都... 目录引言一、Apache HttpClient简介二、技术栈与环境准备三、实现图片下载与保存功能1.

python编写朋克风格的天气查询程序

《python编写朋克风格的天气查询程序》这篇文章主要为大家详细介绍了一个基于Python的桌面应用程序,使用了tkinter库来创建图形用户界面并通过requests库调用Open-MeteoAPI... 目录工具介绍工具使用说明python脚本内容如何运行脚本工具介绍这个天气查询工具是一个基于 Pyt

Ubuntu设置程序开机自启动的操作步骤

《Ubuntu设置程序开机自启动的操作步骤》在部署程序到边缘端时,我们总希望可以通电即启动我们写好的程序,本篇博客用以记录如何在ubuntu开机执行某条命令或者某个可执行程序,需要的朋友可以参考下... 目录1、概述2、图形界面设置3、设置为Systemd服务1、概述测试环境:Ubuntu22.04 带图

Java -jar命令如何运行外部依赖JAR包

《Java-jar命令如何运行外部依赖JAR包》在Java应用部署中,java-jar命令是启动可执行JAR包的标准方式,但当应用需要依赖外部JAR文件时,直接使用java-jar会面临类加载困... 目录引言:外部依赖JAR的必要性一、问题本质:类加载机制的限制1. Java -jar的默认行为2. 类加

java -jar命令运行 jar包时运行外部依赖jar包的场景分析

《java-jar命令运行jar包时运行外部依赖jar包的场景分析》:本文主要介绍java-jar命令运行jar包时运行外部依赖jar包的场景分析,本文给大家介绍的非常详细,对大家的学习或工作... 目录Java -jar命令运行 jar包时如何运行外部依赖jar包场景:解决:方法一、启动参数添加: -Xb