C语言基于栈实现双人消息系统时数组元素被最后存入值覆盖问题
问题原因及修复方案
核心错误点
- 所有存储的消息指针都指向主函数中同一个栈数组
messageToBeSent,每次输入新消息都会覆盖该数组的内容,直接表现为所有历史消息被最新消息覆盖 - 字符串内存分配与拷贝逻辑完全错误:
allocateMemoryForMessage分配内存时未预留字符串结束符\0的存储空间,会触发内存越界- 内存分配完成后直接覆盖指针地址,没有执行字符串内容拷贝,申请的堆内存完全被浪费
- 辅助逻辑错误:
unreadMessages2硬编码仅输出索引0、1的内容,无法适配任意数量的未读消息displayAllMessages2中标记已读的变量赋值错误,误用了另一个消息栈的栈顶变量top
修复代码
1. 修正内存分配逻辑
char* allocateMemoryForMessage(char* msg) { // 额外加1存储字符串结束符 return (char*)malloc((strlen(msg) + 1) * sizeof(char)); }
2. 修正消息存储逻辑,改为拷贝字符串内容而非直接赋值指针
void sendMessageTo2(char* msg) { arrayMsgs2[++top2] = allocateMemoryForMessage(msg); // 拷贝字符串内容到独立的堆内存 strcpy(arrayMsgs2[top2], msg); printf("\nStoring message in the index %d: %s",top2,arrayMsgs2[top2]); return; } void sendMessageTo1(char* msg) { char* newMessage = allocateMemoryForMessage(msg); strcpy(newMessage, msg); push2(newMessage); }
3. 修正辅助功能逻辑
void unreadMessages2() { if(readMsg2>top2) { printf("\nNo messages unread"); return; } printf("\n%d Unread Message(s)",top2 - readMsg2 + 1); // 通用遍历逻辑,替代硬编码输出 while(readMsg2<=top2) { printf("\n%s",arrayMsgs2[readMsg2]); readMsg2++; } } void displayAllMessages2() { if(top2==-1) { printf("\nNo messages to display"); return; } int i; for (i=0;i<=top2;i++) { printf("\n%s", arrayMsgs2[i]); } // 修正为当前消息栈的栈顶top2 readMsg2=top2+1; return; }
4. 可选优化:程序退出前释放所有申请的内存,避免内存泄漏
修改main函数中的退出分支:
case 5: // 释放arrayMsgs1存储的消息内容与数组本身 for(int i=0;i<=top;i++) { free(arrayMsgs1[i]); } free(arrayMsgs1); // 释放arrayMsgs2存储的消息内容与数组本身 for(int i=0;i<=top2;i++) { free(arrayMsgs2[i]); } free(arrayMsgs2); printf("\nExited "); break;
修改完成后每个消息都会存储在独立的堆内存空间,不会再共用同一个栈缓冲区,历史消息被覆盖的问题就会解决。
内容的提问来源于stack exchange,提问作者Smashell
相关产品推荐
相关产品推荐

