首页 > 解决方案 > realloc 在缩小动态数组时返回 NULL

问题描述

函数nodeOutputDel的目的是删除其中一个元素,方法output[]是用最后一个元素替换它,并用realloc但是realloc返回NULL和程序退出来缩小数组errorlevel 11

struct Node
{
    unsigned int *input;
    unsigned int *output;
    unsigned int  inputCount;
    unsigned int  outputCount;
    unsigned int  id;
    bool          state;
};

void nodeOutputDel(struct Node *node, unsigned int id)
{
    unsigned int *newMem, i;
    
    for(i = 0; i < node->outputCount; i++)
    {
        if(node->output[i] == id)
        {
            node->output[i] = node->output[node->outputCount - 1];
            node->outputCount--;
            newMem = realloc(node->output, node->outputCount * sizeof(id));
            if(newMem == NULL) exit(11);
            node->output = newMem;
        }
    }
}

为什么这不起作用?我当然没有内存不足。

编辑:谢谢,我忘记了当最后一个元素消失realloc时返回NULL

标签: cdynamic-arraysrealloc

解决方案


看起来您正在从数组中删除一个项目,但是您需要将所有内容移到数组中该元素的右侧,将一个元素移到左侧。使用 memmove 为您完成繁重的工作。

例如,如果您的 node->output 数组是[11,22,33,44],并且您想从中删除22,您希望将该数组的大小调整为[11,33,44]

而不是这个:

    if(node->output[i] == id)
    {
        node->output[i] = node->output[node->outputCount - 1];
        node->outputCount--;
        newMem = realloc(node->output, node->outputCount * sizeof(id));
        if(newMem == NULL) exit(11);
        node->output = newMem;
    }

这个:

    if(node->output[i] == id)
    {
        // shift all the nodes to right of node->output[i] one slot to the left

        unsigned int shift = node->outputCount - i - 1;
        
        if (shift > 0)
        {
            memmove(node->output+i, (node->output)+(i+1), shift*sizeof(id));
        }
        node->outputCount--;

        if (node->outputCount == 0)
        {
           free(node->output);
           node->output = NULL;
        }
        else
        {
            node->output = realloc(node->output, node->outputCount * sizeof(id));
        }
    }
       

推荐阅读