二维字符VLA指针异常:字符串分割函数返回后字符值变更
问题根源:局部栈内存失效导致野指针访问
你的代码核心问题出在局部数组的生命周期上:
- 在
substring_whitespace函数里,strings是栈上的二维局部数组。函数执行完毕返回时,它所在的栈帧会被销毁,这块内存会被操作系统回收或后续函数调用覆盖。 - 你把
strings[c]的地址赋值给buffer[c],相当于让main里的buffer保存了一堆指向已失效内存的野指针。所以函数返回后再访问这些指针,读取到的就是被篡改的垃圾数据。
修复方案:改用堆内存存储子串
要解决这个问题,需要为每个子串分配堆内存(用malloc),这样内存不会随函数返回而失效。修改后的代码如下:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> size_t substring_whitespace(char* buffer[], char* string) { size_t initial_string_size = strlen(string) + 1; // 动态分配内存保存原字符串副本,避免修改输入 char* actual_string = malloc(initial_string_size); if (!actual_string) { perror("malloc failed"); return 0; } strcpy(actual_string, string); size_t c = 0; while (strlen(actual_string) > 0) { size_t first_whitespace_index = strcspn(actual_string, " "); // 为子串分配内存,+1用于存储字符串终止符 char* substring = malloc(first_whitespace_index + 1); if (!substring) { perror("malloc failed"); // 清理已分配内存避免泄漏 for (size_t i = 0; i < c; i++) { free(buffer[i]); } free(actual_string); return c; } // 复制子串内容并添加终止符 strncpy(substring, actual_string, first_whitespace_index); substring[first_whitespace_index] = '\0'; // 更新剩余字符串 size_t remaining_len = strlen(actual_string) - first_whitespace_index; if (remaining_len > 0 && actual_string[first_whitespace_index] == ' ') { // 跳过空格,移动剩余内容到字符串开头 memmove(actual_string, actual_string + first_whitespace_index + 1, remaining_len); } else { // 无剩余内容,清空字符串 actual_string[0] = '\0'; } buffer[c] = substring; c++; } free(actual_string); return c; } int main() { char string[1000]; fgets(string, sizeof(string), stdin); string[strcspn(string, "\n")] = 0; // 最多可能有strlen(string)+1个单词(极端情况单个字符为一个单词) char* buffer[strlen(string) + 1]; size_t buffer_length = substring_whitespace(buffer, string); for (size_t d = 0; d < buffer_length; d++) { printf("\n%s", buffer[d]); // 使用完毕后释放内存,避免泄漏 free(buffer[d]); } return 0; }
额外优化说明
- 用
malloc分配堆内存,确保子串在函数返回后依然有效。 - 添加内存分配失败的错误处理,避免程序崩溃。
- 用
strncpy和memmove替代手动循环复制,代码更简洁安全。 main中记得释放每个子串的内存,避免内存泄漏。- 简化原代码中手动处理终止符、字符串截取的逻辑,减少出错概率。
内容的提问来源于stack exchange,提问作者Heitor E. Rezende
相关产品推荐
相关产品推荐

