C语言int转string时触发SIGTRAP错误(退出码133)求助
问题分析与修复方案
核心错误点
未初始化堆内存
char* toString = malloc(2 * sizeof(char));分配的内存未初始化,但strcat要求目标字符串必须以\0结尾。这种情况下strcat会从内存中随机寻找终止符,直接触发未定义行为,可能导致内存访问越界或垃圾数据。内存空间不足导致越界写入
初始仅分配2字节内存,但后续拼接数字、逗号、空格等内容时,toString的空间完全不够,strcat会写入到堆内存之外,破坏堆结构,最终触发SIGTRAP信号。无效的内存释放
free(toString);写在return语句之后,永远不会执行,造成内存泄漏。临时缓冲区分配逻辑错误
char *result = malloc(strlen(toString) * sizeof(char ) +1);完全没必要,存储一个32位整数的字符串最多需要12字节(比如INT_MIN是"-2147483648",共11个字符加终止符),此处分配的大小完全不符合需求。
修复后的代码
正确的思路是先计算所需总内存长度,再一次性分配足够空间,最后完成拼接:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <limits.h> #include <assert.h> typedef struct list list_t; struct list { int value; struct list *next; }; // 创建节点的辅助函数 list_t* create_node(int val) { list_t *node = malloc(sizeof(list_t)); node->value = val; node->next = NULL; return node; } char* cdl_to_string(list_t *list){ // 第一步:计算所需总字符串长度 size_t total_len = 2; // "[ ]"的基础长度 list_t *current = list; while (current != NULL) { char num_buf[12]; snprintf(num_buf, sizeof(num_buf), "%d", current->value); total_len += strlen(num_buf); if (current->next != NULL) { total_len += 2; // 加上", "的长度 } current = current->next; } // 分配足够内存并初始化 char* toString = malloc(total_len + 1); // +1 用于存储终止符'\0' if (toString == NULL) { return NULL; // 处理内存分配失败的情况 } strcpy(toString, "["); // 第二步:拼接所有内容 current = list; char *pos = toString + 1; // 从"["后面的位置开始写入 while (current != NULL) { char num_buf[12]; snprintf(num_buf, sizeof(num_buf), "%d", current->value); strcpy(pos, num_buf); pos += strlen(num_buf); if (current->next != NULL) { strcpy(pos, ", "); pos += 2; } current = current->next; } strcpy(pos, "]"); printf("%s\n", toString); return toString; } // 测试函数 void givenListWithMultipleElements_toStringIsOk() { list_t* head = create_node(INT_MIN); list_t* second = create_node(INT_MAX); list_t* third = create_node(0); head->next = second; second->next = third; char* result = cdl_to_string(head); assert(strcmp("[-2147483648, 2147483647, 0]", result) == 0); printf("[ OK ] givenListWithMultipleElements_toStringIsOk\n"); // 释放所有内存 free(result); free(third); free(second); free(head); } int main() { givenListWithMultipleElements_toStringIsOk(); return 0; }
关键优化说明
- 先遍历链表计算总长度,避免多次内存重分配,同时确保内存足够
- 用
snprintf替代sprintf,防止临时缓冲区溢出 - 初始化内存时直接用
strcpy写入"[",确保字符串有合法终止符 - 移除无效的
free操作,同时提醒调用者必须释放函数返回的字符串 - 增加内存分配失败的异常处理
内容的提问来源于stack exchange,提问作者programmmm
相关产品推荐
相关产品推荐

