C语言复制环境变量至新char**缓冲区转小写打印时出现段错误求助
你的C语言程序段错误原因及修复方案
问题分析
你的代码触发段错误主要有三个核心问题:
指针数组内存分配不足
你用malloc(sizeof(environ))只分配了一个指针的内存(64位系统是8字节),但环境变量是一组char*指针组成的数组,需要先统计环境变量的总数,再分配对应数量的指针空间。未为单个字符串分配内存
直接通过**envp_cpy = tolower(*temp)赋值时,envp_cpy指向的char*根本没有分配内存空间,属于非法内存访问,必然触发段错误。每个环境变量的字符串都需要单独分配内存来存储转换后的小写内容。缺少终止符
转换字符串时没有添加'\0'结尾,且最后没有给envp数组添加NULL终止标记,会导致后续printf或循环读取越界。
修复后的代码
#include <ctype.h> // tolower() #include <stdlib.h> // malloc(), free() #include <stdio.h> // printf() #include <string.h> // strlen() extern char **environ; int main() { int count = 0; // 先统计环境变量的数量 while (environ[count] != NULL) { count++; } // 分配指针数组的内存,+1是为了存储最后的NULL char **envp = malloc((count + 1) * sizeof(char*)); if (envp == NULL) { perror("malloc failed"); return 1; } for (int i = 0; i < count; i++) { const char *src = environ[i]; size_t len = strlen(src); // 为当前环境变量的小写字符串分配内存 envp[i] = malloc(len + 1); // +1存储'\0' if (envp[i] == NULL) { perror("malloc failed"); // 之前分配的内存要释放,避免泄漏 for (int j = 0; j < i; j++) { free(envp[j]); } free(envp); return 1; } // 逐个字符转小写并复制 char *dest = envp[i]; while (*src != '\0') { *dest = tolower((unsigned char)*src); // 转unsigned char避免未定义行为 dest++; src++; } *dest = '\0'; // 添加字符串终止符 } envp[count] = NULL; // 指针数组的终止标记 // 打印转换后的环境变量 for (int i = 0; envp[i] != NULL; i++) { printf("%s\n", envp[i]); } // 释放内存:先释放每个字符串,再释放指针数组 for (int i = 0; envp[i] != NULL; i++) { free(envp[i]); } free(envp); return 0; }
关键修复点说明
- 统计环境变量数量:先遍历
environ拿到总数,确保指针数组分配足够空间。 - 分层内存分配:先分配存储
char*的指针数组,再为每个环境变量字符串单独分配内存。 - 添加终止符:每个转换后的字符串末尾加
'\0',指针数组最后加NULL,保证字符串和数组的完整性。 - 错误处理:添加
malloc失败的判断,避免内存泄漏。 - tolower的安全调用:把
*src转成unsigned char,避免处理负数字符时的未定义行为。
内容的提问来源于stack exchange,提问作者Bar Minz
相关产品推荐
相关产品推荐

