You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
}

核心修复说明

  1. 字符串内存分配修正:将malloc(strlen(buff))改为malloc(strlen(buff) + 1),为'\0'预留空间,彻底解决strcpy越界问题。
  2. 野指针初始化:main中显式将head初始化为NULL,避免未定义行为。
  3. 完善内存管理:pop函数先释放节点内的字符串,再释放节点;程序结束前调用destroy清理所有节点,杜绝内存泄漏。
  4. 添加错误检查:对malloc的返回值进行检查,避免内存分配失败引发后续崩溃。
  5. 修正循环逻辑:原代码中strcmp("x", buffer)作为循环条件时,返回0(即输入"x")会被视为真,导致无法退出,改为strcmp(...) != 0才符合需求。

内容的提问来源于stack exchange,提问作者stfp04

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 21:05:44