c - 可以找出函数内部我的 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);
}
我无法理解发生了什么,有人可以帮助我吗?
解决方案
当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
也应该大于零。
推荐阅读
- python - 来自 csv 文件的字典列表
- javascript - 将页面的所有样式保留在页面块元素内
- python - 将 statistics.stdev 值转换为 np.std 值
- python - readline(argument) 导致“TypeError:str to integer”,但不应该改变格式
- jenkins - 需要将shell命令更改为groovy
- git - 使用 git bash 时无法推送到存储库
- c# - 内存中的 CSharpCompilation 无法解析属性
- python - 如何修复“HTTP CONNECTION FAILED”错误
- python - 如何为 DataFrame 中的每一行运行一个函数?
- java - @DataJpaTest 与 SpringBoot - 不抛出 OptimisticLocking 异常