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

为何循环外部指针被覆盖?C语言链表指针异常排查

问题排查:二进制场景文件阅读器链表指针损坏

以下是导致链表指针损坏的核心问题及修复方案:


1. 栈内存指针悬空(触发损坏的直接原因)

在LoadScenes函数的纹理循环中,file_name是栈上分配的局部数组:

char file_name[file_name_length];
__READ_STRING(file_name, file_name_length, scene_file);

当纹理循环迭代结束时,栈帧销毁,file_name的内存被释放。但创建Node时直接将Node->name指向这个栈内存:

__CreateNode(texture, file_name, loaded_texture)

循环外访问current_scene->scene_contents时,Node->name指向已释放的栈内存,触发未定义行为(表现为指针损坏、数据乱码)。

修复方案:
为文件名分配堆内存,避免栈内存失效:

// 替换原file_name的定义
char* file_name = malloc(file_name_length + 1);
if (!file_name) {
    PrintError("Failed to allocate filename buffer.");
    continue; // 跳过当前纹理,避免后续错误
}
__READ_STRING(file_name, file_name_length, scene_file);

// 创建Node后,文件名指针会被保留,需在Node销毁时同步释放该内存

2. __MALLOC宏语法错误(导致内存分配失效)

__MALLOC宏存在严重语法问题,展开后不会将malloc的返回值赋值给目标变量:

#define __MALLOC(type, allocated, error_message)                     \
    malloc(sizeof(type));                                            \
    if (allocated == NULL) (PrintError "Failed to allocate the texture '%s'. Code: %d.", name, errno)

展开后逻辑变成:

malloc(sizeof(Texture)); // 返回值直接丢弃
if (texture == NULL) { ... } // texture未被赋值,为随机垃圾值

这会导致texture、current_scene等变量成为野指针,后续操作直接破坏内存。

修复方案:
修正宏的语法,正确赋值malloc返回值:

#define __MALLOC(type, allocated, error_msg, ...)                   \
    do {                                                             \
        allocated = (type*)malloc(sizeof(type));                     \
        if (allocated == NULL) {                                     \
            PrintError(error_msg, ##__VA_ARGS__);                    \
            exit(EXIT_FAILURE); // 终止程序,避免非法访问             \
        }                                                            \
    } while(0)

使用时调整参数传递:

Texture* texture = NULL;
__MALLOC(Texture, texture, "Failed to allocate the texture '%s'. Code: %d.", name, errno);

3. 其他潜在风险

  • AppendNode空指针检查:如果list->last_node为NULL(链表未正确初始化),会触发空指针解引用。建议添加保护逻辑:
    void AppendNode(LinkedList* list, Node* node)
    {
        if (!list || !node) return;
        if (!list->first_node) {
            list->first_node = node;
            list->last_node = node;
            node->next = NULL;
            return;
        }
        list->last_node->next = node;
        list->last_node = node;
        node->next = NULL;
    }
    
  • ReadFromFile错误处理:当前仅打印错误但未终止程序,会导致后续代码使用无效数据,加剧内存损坏。建议在打印错误后添加exit(EXIT_FAILURE)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 20:34:53