Ubuntu下C语言项目出现free(): invalid pointer错误排查求助
链表内存释放时出现
free(): invalid pointer错误的排查与修复 问题场景
我有一个约2000行代码的C语言项目,使用链表存储程序数据。程序结束时调用自定义的freeSymbolTable函数释放链表内存,却触发如下错误:
free(): invalid pointer
Aborted (code dumped)
所有链表节点均通过insertSymbol函数在堆内存上分配,链表相关代码如下:
SymbolTable.h 文件内容
#ifndef SYMBOL_TABLE_H #define SYMBOL_TABLE_H #include <stdio.h> #include <stdlib.h> #include <string.h> #include "constants.h" /** * a struct holding the SymbolTable information */ typedef struct SymbolTable { char* symbol; unsigned int identifier:2; int value; struct SymbolTable *next; } SymbolTable; extern SymbolTable* symbol_table; /** * Function insertSymbol * --------------------- * gets the symbol information (e.g. symbol name, identefier and value) * and insert it to the symbol table * * @param symbol: string holding the symbol name * @param identerfier: an integer holding the id of the symbol (e.g. .code, .mdefine or .data) * @param value: the value of the symbol in the memory */ void insertSymbol(const char* symbol, const int identifier, const int value); /** * Function lookupSymbol * ---------------------- * searching a symbol in the symbol table * * @param symbol: a string holding the symbol name to search * * @return a pointer to the symbol matching the name passed as an argument */ SymbolTable* lookupSymbol(const char* symbol); /** * Function freeSymbolTable * ------------------------ * releasing the memory that was allocated to the symbol_table data structure */ void freeSymbolTable(); #endif
对应源文件内容
#include "../headers/symbolTable.h" SymbolTable* symbol_table = NULL; void insertSymbol(const char *symbol, const int identifier, const int value) { SymbolTable **temp = &symbol_table; while (*temp != NULL) { temp = &(*temp)->next; } *temp = (SymbolTable*)calloc(1, sizeof(SymbolTable)); (*temp)->symbol = (char*)calloc(strlen(symbol) + 1, sizeof(char)); strcpy((*temp)->symbol, symbol); (*temp)->identifier = identifier; (*temp)->value = value; (*temp)->next = NULL; } SymbolTable* lookupSymbol(const char *symbol) { SymbolTable *temp = symbol_table; /* iterating over the symbol table and returning a pointer to the symbol if it was found otherwise returning null */ while (temp != NULL) { if (strcmp(temp->symbol, symbol) == 0) { return temp; } temp = temp->next; } return NULL; } void freeSymbolTable() { /* iterating over the symbol table and releasing the memory that was allocated for it */ SymbolTable *temp = NULL; while (symbol_table != NULL) { temp = symbol_table; symbol_table = symbol_table->next; free(temp); temp = NULL; } }
注:项目中所有添加节点的操作均通过调用insertSymbol函数完成,未自行添加节点,问题应出在上述代码中。
问题根源
- 未释放节点内的堆内存:每个
SymbolTable节点的symbol字段是通过calloc单独分配的堆内存,但freeSymbolTable只释放了节点结构体本身,没有释放symbol指向的内存。这会导致内存泄漏,且如果后续代码中意外访问或释放这些未被清理的指针,就会触发invalid pointer错误。 - 全局变量操作风险:
freeSymbolTable直接修改全局变量symbol_table,如果释放过程中有其他代码(比如多线程场景)修改该变量,会导致指针混乱;另外,若有其他地方保存了旧的节点指针,释放后再访问也会引发错误。
修复方案
修正后的freeSymbolTable函数
void freeSymbolTable() { SymbolTable *current = symbol_table; SymbolTable *next_node = NULL; while (current != NULL) { next_node = current->next; // 先释放节点内的symbol字符串内存 free(current->symbol); // 再释放节点结构体本身 free(current); current = next_node; } // 最后将全局表头置空,避免野指针 symbol_table = NULL; }
额外优化建议
- 添加内存分配检查:
insertSymbol中未检查calloc的返回值,若内存分配失败会导致空指针操作,建议添加错误处理:*temp = (SymbolTable*)calloc(1, sizeof(SymbolTable)); if (!*temp) { perror("Failed to allocate symbol table node"); exit(EXIT_FAILURE); } (*temp)->symbol = (char*)calloc(strlen(symbol) + 1, sizeof(char)); if (!(*temp)->symbol) { perror("Failed to allocate symbol string"); free(*temp); exit(EXIT_FAILURE); } - 避免重复插入:
insertSymbol未检查符号是否已存在,重复插入会导致冗余节点,建议插入前调用lookupSymbol确认:if (lookupSymbol(symbol)) { // 符号已存在,可选择报错或跳过 fprintf(stderr, "Symbol %s already exists\n", symbol); return; } - 减少全局变量依赖:尽量将链表表头作为参数传递给相关函数,降低全局变量带来的耦合和副作用。
内容的提问来源于stack exchange,提问作者roee
相关产品推荐
相关产品推荐

