C语言字符串反转程序遇Segmentation fault及free释放未分配对象问题
问题分析与修复
核心问题1:字符串常量被修改导致段错误
main函数中,你先通过malloc分配了内存给result,但随后直接将result赋值为字符串常量"Forty-two":
char* result = (char*)(malloc(sizeof(char) * 10)); result = "Forty-two"; // 覆盖了malloc返回的地址,指向只读的字符串常量
字符串常量存储在程序的只读数据段,尝试修改它(reverseString中str[i] = temp[i])会触发Segmentation fault。同时,后续free(result)释放的是字符串常量的地址,而非malloc分配的内存,因此会出现'free' called on a pointer to an unallocated object警告。
核心问题2:临时内存分配错误
reverseString中malloc的大小计算错误:
char *temp = (char*) malloc(sizeof(str) + 1);
sizeof(str)得到的是指针类型的大小(通常4或8字节),不是字符串的实际长度。应该根据传入的size参数来分配,即size + 1(+1是为了存储字符串终止符'\0')。
核心问题3:字符串索引越界
循环中j初始值为size,而字符串的有效索引范围是0到size-1,str[j]访问的是字符串终止符'\0',会导致反转后的字符串开头是空字符,后续字符错位。
核心问题4:临时字符串未添加终止符
复制完成后,temp没有添加字符串终止符'\0',会导致后续操作出现未定义行为。
修复后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> void reverseString(char* str, size_t size) { // 根据实际长度分配内存,+1用于存储'\0' char *temp = (char*) malloc(size + 1); if (temp == NULL) { // 检查malloc是否成功 return; } int j = size - 1; // 从最后一个有效字符开始 for (int i = 0; i < size; i++) { temp[i] = str[j]; j--; } temp[size] = '\0'; // 添加字符串终止符 // 将反转后的内容复制回原字符串 for (int i = 0; i < size; i++) { str[i] = temp[i]; } free(temp); } int main() { // 分配足够内存并复制字符串常量到堆内存 char* result = (char*)malloc(sizeof(char) * 10); if (result == NULL) { return 1; } strcpy(result, "Forty-two"); // 使用strcpy将字符串常量复制到堆内存 size_t len = strlen(result); reverseString(result, len); printf("%s\n", result); free(result); // 释放的是malloc分配的堆内存,无警告 result = NULL; return 0; }
额外优化提示
- 可以直接在原字符串上进行反转(无需临时内存),通过交换首尾字符的方式,节省内存开销:
void reverseString(char* str, size_t size) { for (int i = 0; i < size / 2; i++) { char temp = str[i]; str[i] = str[size - 1 - i]; str[size - 1 - i] = temp; } }
内容的提问来源于stack exchange,提问作者Illya Kuzmych
相关产品推荐
相关产品推荐

