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

C语言动态字符串数组库存系统的内存异常问题排查

C语言动态库存系统内存访问问题排查与解决

问题现象

  • 单次调用addItemToInventory添加物品,主函数能正常输出内容
  • 第二次调用后,主函数中第二个物品显示为NULL
  • 第三次及以上调用直接触发段错误
  • 函数内部末尾打印新添加的物品内容正常,但返回主函数后对应位置数据丢失

问题根源

核心问题是运算符优先级错误:数组下标运算符[]的优先级高于解引用运算符*。代码中*Inv_content[0]、*Inv_content[*Inv_length]这类写法,实际执行逻辑是先取Inv_content(三级指针)的下标元素再解引用,完全违背了我们的意图——我们需要先解引用Inv_content得到二级指针(库存字符串数组),再访问数组对应下标元素。

这种错误导致malloc分配的字符串地址没有被正确存入库存数组,反而写入了非法内存区域,进而出现主函数数据丢失、越界访问崩溃的现象。

修复方案

将所有错误的*Inv_content[index]写法修改为(*Inv_content)[index],确保先解引用得到库存数组,再操作对应下标元素。修复后的完整代码如下:

修复后的addItemToInventory函数

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int addItemToInventory(char ***Inv_content,int *Inv_length,char* Item)
{
    int item_name_size=strlen(Item);
    if (*Inv_length==0) // 库存为空时创建数组
    {
        *Inv_content = malloc(1 * sizeof(char*));
        if (*Inv_content) // 数组内存分配成功
        {
            (*Inv_content)[0] = malloc((item_name_size+1) * sizeof(char));
            if ((*Inv_content)[0]) // 物品内存分配成功
            {
                strcpy((*Inv_content)[0], Item);
                *Inv_length += 1;
            }
            else // 物品内存分配失败
            {
                printf("无法为物品 '%s' 分配内存(InvContent[0])\n", Item);
                free(*Inv_content); // 释放已分配的数组内存,避免泄漏
                *Inv_content = NULL;
                return 2;
            }
        }
        else // 数组内存分配失败
        {
            printf("无法为库存分配内存(创建新库存)\n");
            return 1;
        }
    }
    else // 库存非空时扩容并添加物品
    {
        char **tmp_pnt;
        tmp_pnt = realloc(*Inv_content, (*Inv_length+1) * sizeof(char*));

        if (tmp_pnt)
        {
            *Inv_content = tmp_pnt;
            (*Inv_content)[*Inv_length] = malloc((item_name_size+1) * sizeof(char));

            if ((*Inv_content)[*Inv_length])
            {
                strcpy((*Inv_content)[*Inv_length], Item);
                *Inv_length += 1;
            }
            else // 物品内存分配失败
            {
                printf("无法为物品 '%s' 分配内存(InvContent[%d])\n", Item, *Inv_length);
                return 2;
            } 
        }
        else // 扩容内存分配失败
        {
            printf("无法为库存分配内存(添加物品:realloc)\n");
            return 1;
        }
    }
    return 0;
}

测试用主函数(含内存释放优化)

int main()
{
    char **Inv_content = NULL;
    int Inv_length=0;
    char Item1[12]="Great Sword";
    char Item2[8]="Big Bow";
    char Item3[10]="Fire Staff"; // 新增测试物品

    addItemToInventory(&Inv_content, &Inv_length, Item1);
    addItemToInventory(&Inv_content, &Inv_length, Item2);
    addItemToInventory(&Inv_content, &Inv_length, Item3); // 第三次调用测试

    printf("\n");
    for (int i=0; i<Inv_length;i++)
    {
        printf ("物品 %d : %s \n", i+1, Inv_content[i]);
    }

    // 释放内存,避免泄漏
    for (int i=0; i<Inv_length; i++) {
        free(Inv_content[i]);
    }
    free(Inv_content);
    return 0;
}

验证结果

修复后运行代码,输出如下:

物品 1 : Great Sword 
物品 2 : Big Bow 
物品 3 : Fire Staff 

所有物品正常显示,多次调用不再触发段错误,主函数能正确读取库存数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 19:27:07