C语言栈与动态内存问题:单词逆序程序编译报错求助
解决单链表栈实现中的内存分配与越界问题
报错根源解析
- strcpy越界写入:C语言字符串以
'\0'作为结束标记,strlen(buff)仅返回有效字符长度,不包含这个终止符。代码中用malloc(sizeof(char) * strlen(buff))分配的内存刚好容纳字符,但strcpy会额外写入一个'\0',触发越界报错。 - malloc大小异常:若传入空字符串(尽管当前
scanf("%s")不会读入空串,但逻辑上存在风险),strlen(buff)返回0,此时malloc(0)的行为未定义,会导致分配的内存大小出现异常范围。 - 未初始化野指针:
main里的head未初始化就传入push,会引发非法内存访问。 - 内存泄漏:
pop只释放了节点结构体,没释放节点中存储的字符串内存,长期运行会造成内存泄漏。
修复后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_NOME 256 typedef struct stru_node { struct stru_node *next; char *v; } node; node *pop(node *head) { if (head != NULL) { node *next_node = head->next; free(head->v); // 先释放字符串内存 free(head); // 再释放节点本身 return next_node; } return NULL; } node *push(node *head, const char *buff) { size_t str_len = strlen(buff); // 分配节点内存并检查是否成功 node *link = (node*)malloc(sizeof(node)); if (!link) { perror("Failed to allocate node"); return head; } // 为字符串分配内存,预留终止符空间 link->v = (char*)malloc(str_len + 1); if (!link->v) { perror("Failed to allocate string"); free(link); return head; } strcpy(link->v, buff); link->next = head; return link; } node *destroy(node *head) { while (head != NULL) { head = pop(head); } return NULL; } void print(node *head) { node *link = head; while (link != NULL) { printf("%s\n", link->v); link = link->next; } } int main() { char buffer[MAX_NOME]; node *head = NULL; // 初始化头指针为NULL // 修正循环退出条件:输入"x"时终止循环 while (scanf("%s", buffer) != EOF && strcmp("x", buffer) != 0) { head = push(head, buffer); } print(head); destroy(head); // 程序结束前释放所有内存 return 0; }
核心修复说明
- 字符串内存分配修正:将
malloc(strlen(buff))改为malloc(strlen(buff) + 1),为'\0'预留空间,彻底解决strcpy越界问题。 - 野指针初始化:
main中显式将head初始化为NULL,避免未定义行为。 - 完善内存管理:
pop函数先释放节点内的字符串,再释放节点;程序结束前调用destroy清理所有节点,杜绝内存泄漏。 - 添加错误检查:对
malloc的返回值进行检查,避免内存分配失败引发后续崩溃。 - 修正循环逻辑:原代码中
strcmp("x", buffer)作为循环条件时,返回0(即输入"x")会被视为真,导致无法退出,改为strcmp(...) != 0才符合需求。
内容的提问来源于stack exchange,提问作者stfp04
相关产品推荐
相关产品推荐

