首页 > 解决方案 > 可以找出函数内部我的 realloc 的问题

问题描述

我正在编写一个程序,该程序需要调用一个添加数字直到引入 -1 的函数,问题是在 3 个数字之后程序停止并给出分段错误:

int leNumeros(int **lista, int *nElem, int *tam)
{
    int op, *temp = NULL;
    *lista = (int*) malloc(*tam * sizeof(int));

    if(*lista == NULL)
    {
        printf("memory fail\n");
    } else
    {
        do
        {
            printf("number:\n");
            scanf("%d",&op);

            if(op >= 0)
            {
                if(*nElem >= *tam)
                {
                *lista = (int*) realloc( *lista, *nElem * sizeof(int) );

                if(*lista == NULL)
                {
                    printf("memory fail");
                }
                else
                {
                    printf("added: %d bytes total: %d bytes\n",
                            *nElem * sizeof(int), *nElem * sizeof(int) + *tam * sizeof(int));
                    //*lista = temp;
                }
                }
                *lista[*nElem] = op;
                (*nElem)++;



            }
        }while(op >= 0);
    }    
}


int main(int argc, char** argv) {

    int *lista = NULL, nElem = 0, tam = 0;

    leNumeros(&lista, &nElem, &tam);

    return (EXIT_SUCCESS);
}

我无法理解发生了什么,有人可以帮助我吗?

标签: c

解决方案


leNumeros()被调用时,您会尝试分配一个长度为零的块,该块具有实现定义的行为

然后,当您输入一个大于 0 的数字时,您尝试realloc()使用零长度块 - 该行为已明确定义,它释放原始块然后返回一个空指针,然后在*lista[*nElem] = op;您尊重该空指针而不是中止循环。

在任何情况下*lista[*nElem] = op;都应该(*lista)[*nElem] = op;

即使 *nElem非零,该行:

*lista = (int*)realloc(*lista, *nElem * sizeof(int));

是不好的做法,因为如果重新分配失败,原始块将泄漏,因为 *lista 将变为 NULL 而不会释放它先前指向的任何内容。相反,您应该(例如):

int* new_block = realloc(*lista, *nElem * sizeof(int));
if( new_block == NULL )
{
    printf( "memory fail\n" ) ;
    break ;
}

*lista = new_block ;

要完全在 main 中工作,tam必须大于 0,并且为了避免由于实现定义的行为而可能导致的失败,nElem也应该大于零。


推荐阅读