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

C语言通用类型is_in函数判断指针存在性出错问题排查

通用is_in函数的问题分析与修复

核心错误点

  • 数组越界写入:pptest仅分配了2个Symbol*的存储空间,有效下标范围是0和1,但测试代码中错误使用了pptest[2]进行赋值,这属于未定义行为,&F根本没有被存入数组的有效区域内。
  • void*指针算术非法:is_in函数里的array + k是错误操作,C标准中void类型无法直接做指针算术——编译器不知道其指向元素的字节大小。必须参考qsort的设计,增加元素大小参数,通过char来计算正确的内存偏移。
  • 参数类型不匹配:调用is_in时传入的pelement是&F(即Symbol**类型),但ptreq函数中将ptr2强制转换为Symbol*,导致比较逻辑完全错误;同时is_in传给equals的第一个参数是错误偏移的指针,没有正确指向数组中的元素。
  • 字符串内存分配错误:set_symbol函数中malloc(sizeof(content))仅分配了指针大小的空间,而非字符串实际需要的长度+1的空间,会导致缓冲区溢出。

修正后的完整代码

修复后的is_in函数(新增元素大小参数)

int is_in(void* array, int size, size_t elem_size, void* pelement, int (*equals)(void* this, void* that)) {
    char* arr_base = (char*)array;
    for(int k = 0; k < size; k++) {
        // 计算第k个元素的内存地址
        void* current_elem = arr_base + k * elem_size;
        if(equals(current_elem, pelement)) {
            return 1;
        }
    }
    return 0;
}

修复后的ptreq函数(匹配参数类型)

int ptreq(void* ptr1, void* ptr2) {
    // ptr1是数组中元素的地址(Symbol**),ptr2是传入的目标地址(Symbol**)
    return *(Symbol**)ptr1 == *(Symbol**)ptr2;
}

修复测试代码(修正越界+内存分配错误)

enum SymbolType {
    TERMINAL,
    NONTERMINAL
} typedef SymbolType;

struct Symbol {
    char* content;
    SymbolType type;
} typedef Symbol;

void set_symbol(Symbol* pS, SymbolType type, char* content) {
    // 为字符串分配足够空间:长度+1(存储结束符)
    pS->content = malloc(strlen(content) + 1);
    strcpy(pS->content, content);
    pS->type = type;
}

int main(int argc, char* argv[]) {
    Symbol F, E;
    set_symbol(&E, NONTERMINAL, "E");
    set_symbol(&F, NONTERMINAL, "F");

    Symbol** pptest = malloc(2 * sizeof(Symbol*));
    pptest[0] = &E;
    // 修正数组下标为1,避免越界
    pptest[1] = &F;

    // 调用时传入元素大小:sizeof(Symbol*)
    printf("Is F in pptest? %d\n", is_in(pptest, 2, sizeof(Symbol*), &F, ptreq));

    // 释放内存,避免泄漏
    free(E.content);
    free(F.content);
    free(pptest);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 11:20:37