malloc分配字符串数组未达预期,求字符串拆分函数实现指导
解决字符串拆分函数中二级指针的malloc分配问题
Hey,看来你在实现字符串拆分函数的时候卡在了二级指针的内存分配上,我来帮你捋清楚这个问题~ 你的需求是把输入字符串拆成单个单词,用malloc分配内存后存入传入的字符串数组指针里,咱们一步步来搞定:
首先得明确两个核心步骤:先统计输入里的单词数量,这样才知道要给指针数组分配多少个char*的位置;再逐个为每个单词分配字符数组内存,把拆分后的内容拷贝进去。我给你补全并优化了代码,同时解释关键部分:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> int string_parser(char *inp, char **array_of_words_p[]) { // 先处理空指针输入的边界情况 if (inp == NULL || array_of_words_p == NULL) { return -1; } int CurrentChar = 0; int word_count = 0; int in_word = 0; // 第一步:统计字符串里的单词总数 while (inp[CurrentChar] != '\0') { if (isspace(inp[CurrentChar])) { in_word = 0; } else if (!in_word) { in_word = 1; word_count++; } CurrentChar++; } // 如果没有找到任何单词,直接返回0并置空指针数组 if (word_count == 0) { *array_of_words_p = NULL; return 0; } // 第二步:分配存储char*指针的数组(也就是你卡住的二级指针内存) // 这里+1是为了在数组末尾放一个NULL标记,方便调用者遍历判断结束 *array_of_words_p = (char**)malloc(sizeof(char*) * (word_count + 1)); if (*array_of_words_p == NULL) { return -1; // 内存分配失败返回错误码 } // 第三步:拆分字符串,为每个单词分配内存并拷贝内容 CurrentChar = 0; int word_index = 0; int word_start = 0; in_word = 0; while (inp[CurrentChar] != '\0') { if (isspace(inp[CurrentChar])) { if (in_word) { // 计算当前单词的长度 int word_len = CurrentChar - word_start; // 分配单词内存,+1用来存字符串终止符'\0' (*array_of_words_p)[word_index] = (char*)malloc(sizeof(char) * (word_len + 1)); if ((*array_of_words_p)[word_index] == NULL) { // 万一内存分配失败,得把已经分配的内存全部释放,避免泄漏 for (int i = 0; i < word_index; i++) { free((*array_of_words_p)[i]); } free(*array_of_words_p); *array_of_words_p = NULL; return -1; } // 拷贝单词到分配的内存里 strncpy((*array_of_words_p)[word_index], inp + word_start, word_len); // 手动加终止符,因为strncpy不会自动补'\0' (*array_of_words_p)[word_index][word_len] = '\0'; word_index++; in_word = 0; } } else if (!in_word) { word_start = CurrentChar; in_word = 1; } CurrentChar++; } // 处理字符串末尾的最后一个单词(如果字符串不以空格结尾) if (in_word) { int word_len = CurrentChar - word_start; (*array_of_words_p)[word_index] = (char*)malloc(sizeof(char) * (word_len + 1)); if ((*array_of_words_p)[word_index] == NULL) { // 同样要清理已分配内存 for (int i = 0; i < word_index; i++) { free((*array_of_words_p)[i]); } free(*array_of_words_p); *array_of_words_p = NULL; return -1; } strncpy((*array_of_words_p)[word_index], inp + word_start, word_len); (*array_of_words_p)[word_index][word_len] = '\0'; word_index++; } // 在指针数组末尾添加NULL,标记数组结束 (*array_of_words_p)[word_index] = NULL; return word_count; // 返回拆分出的单词数量,方便调用者处理 }
关键细节解释
- 统计单词数量:用
isspace判断所有空白字符(空格、制表符、换行等),通过in_word标记当前是否处于单词中,这样能准确统计出单词总数——这是分配二级指针的核心依据,不然你根本不知道要分配多少个char*位置 - 二级指针的分配:因为函数参数是
char **array_of_words_p[],本质是指向二级指针的指针,所以必须用*array_of_words_p来接收malloc返回的地址;额外多分配一个位置存NULL,是为了让调用者可以通过遍历到NULL来判断数组结束,避免越界 - 单个单词的内存管理:每次找到单词的起止位置后,计算长度再分配对应内存,拷贝后手动加
'\0'(strncpy不会自动添加终止符,这很容易踩坑) - 错误处理:如果中途
malloc失败,一定要回溯释放已经分配的内存,不然会造成内存泄漏,这是C语言内存管理的基本素养
调用后的注意事项
调用这个函数后,调用者需要负责释放所有分配的内存,示例如下:
int main() { char input[] = "Hello world this is a test string"; char **words = NULL; int count = string_parser(input, &words); if (count > 0) { for (int i = 0; words[i] != NULL; i++) { printf("%s\n", words[i]); free(words[i]); // 先释放每个单词的内存 } free(words); // 再释放指针数组的内存 } return 0; }
内容的提问来源于stack exchange,提问作者saber112
相关产品推荐
相关产品推荐

