遍历char指针时赋值触发段错误,求char*转char*[]的正确实现
段错误原因分析
你触发段错误的核心原因是试图修改字符串常量:
- 在
main函数里,char *str = "my_program -f 1 -o out.txt";定义的是指向字符串常量的指针,这类字符串存储在程序的只读内存区域,不允许被修改。 split函数里的*it = '\0';试图把原字符串中的空格替换为结束符,本质是修改只读内存的内容,直接触发内存访问错误(段错误)。
正确实现方式
解决思路是先把原字符串拷贝到一块可写的堆内存中,再对拷贝后的字符串进行分割操作,同时修正原逻辑里的边界问题:
#include <stdlib.h> #include <stdio.h> #include <string.h> void f(char* const args[]){ for( int i = 0; args[i] != NULL; ++i ){ printf("%s\n", args[i]); } } char** split(char* str, char tok){ // 拷贝原字符串到可写内存 size_t len = strlen(str); char* writable_str = malloc(len + 1); if (!writable_str) { perror("malloc failed"); return NULL; } strcpy(writable_str, str); // 计算分割后的元素数量 int num = 1; // 非空字符串至少有一个元素 char* it = writable_str; while (*it != '\0') { if (*it == tok) { num++; } it++; } // 分配结果数组空间(+1 用于存储NULL结束标记) char** result = malloc((num + 1) * sizeof(char*)); if (!result) { perror("malloc failed"); free(writable_str); return NULL; } // 填充结果数组 int j = 0; it = writable_str; result[j++] = it; while (*it != '\0') { if (*it == tok) { *it = '\0'; // 跳过连续的分隔符,避免生成空元素 while (*(it+1) == tok) { it++; } result[j++] = it + 1; } it++; } result[j] = NULL; // 用NULL标记数组末尾 return result; } int main (){ const char *str = "my_program -f 1 -o out.txt"; char** split_str = split((char*)str, ' '); if (split_str) { f(split_str); // 释放内存,避免泄漏 free(split_str[0]); // 释放拷贝的字符串 free(split_str); // 释放结果数组 } return 0; }
关键修改说明
- 新增可写内存拷贝:用
malloc分配可写空间,复制原字符串后再操作,避免修改只读内存。 - 修正元素计数逻辑:初始元素数设为1,通过统计分隔符数量确定最终元素个数。
- 处理连续分隔符:避免生成空的参数元素,保证分割结果的有效性。
- 补充内存释放:在
main中添加内存释放逻辑,修复原代码的内存泄漏问题。
内容的提问来源于stack exchange,提问作者infinitezero
相关产品推荐
相关产品推荐

