C语言字符串终止符异常排查:链表单词复制到数组时的字符访问bug
链表单词复制数组时的字符访问异常问题解析
兄弟,我一眼就看穿了你的问题根源——临时缓冲区wordy的类型定义完全错了,这直接导致了内存操作混乱,才出现了printf打印正常但单个字符访问异常的诡异现象。
问题核心:错误的变量类型
你定义的char* wordy[100];是一个存储字符指针的数组,而不是用来存放单个单词字符的字符数组。这就好比你拿一个装文件路径的文件夹去装文字,完全不匹配。
当你执行strcat(wordy, giveWord(pCounter))时,strcat需要的第一个参数是char*类型的字符数组起始地址,但你传入的是指针数组的地址。这时候strcat会把单词的字节直接写到指针数组的内存空间里:
- 比如单词"one"的字节是
'o'、'n'、'e'、'\0',这些字节会被依次写入指针数组的前几个字节位置。 - 而你访问
wordy[1]时,取的是指针数组的第二个元素(一个8字节或4字节的指针值),因为你的数组是全局变量(默认初始化为0),这个位置的初始值就是0,所以会触发printf("is 0");。 - 至于
printf("WORDY: %s \n",wordy);能正常打印,是因为printf的%s会从你传入的地址(指针数组的起始地址)开始逐字节读取,直到遇到'\0',刚好这些字节组成了"one",所以看起来正常,但本质是在错误的内存区域读写。
修复步骤
1. 修正临时缓冲区类型
把wordy改成真正的字符数组,用来存储单个单词:
char wordy[100]; // 原来是char* wordy[100]; 现在修正为字符数组
2. 修正字符串复制逻辑
因为每次循环都会清空wordy,用strcpy代替strcat更准确(strcat是追加,strcpy是直接覆盖,符合我们复制单个单词的需求):
strcpy(wordy, giveWord(pCounter));
3. 修复内存分配与索引问题
- 你的
exactly_word需要额外分配存储每个单词末尾'\0'的空间,总内存应该是num_car + readed_nd_word(readed_nd_word是单词总数,每个单词对应一个'\0')。 - 原来的
indice_parole;是无效代码,必须自增,否则下一个单词会覆盖掉刚写入的'\0'。
修正后的完整代码片段
char wordy[100]; // 修正为字符数组,用于临时存储单个单词 pCounter = pStart; // pStart是链表头指针 // 分配足够内存:总字符数 + 每个单词的终止符数量 exactly_word = malloc(sizeof(char)*(num_car + readed_nd_word)); int indice = 0; int indice_parole = 0; for(int x=0; x<readed_nd_word;x++){ counters[x] = giveCounter(pCounter); strcpy(wordy, giveWord(pCounter)); // 复制当前单词到临时缓冲区 printf("WORDY: %s \n",wordy); // 现在打印和字符访问都会正常 // 逐字符复制到exactly_word while(wordy[indice]!= 0){ printf("Char to insert %c \n",wordy[indice]); exactly_word[indice_parole] = wordy[indice]; indice_parole++; indice++; } exactly_word[indice_parole] = '\0'; // 写入当前单词的终止符 indice_parole++; // 移动到下一个单词的起始位置 pCounter = pCounter -> pNext; // 遍历下一个节点 memset(wordy,0,100); // 清空临时缓冲区 indice = 0; }
额外注意点
- 记得在使用完
exactly_word后调用free(exactly_word);,避免内存泄漏。 - 后续可以检查
malloc的返回值,如果为NULL说明内存分配失败,需要处理这种异常情况。
内容的提问来源于stack exchange,提问作者Gabriele Pisapia
相关产品推荐
相关产品推荐

