我是c中动态分配的新手,我在调用free()
函数时遇到堆损坏错误。
整个代码应该模拟重新分配函数realloc()
,它可以正常工作直到结束。我一步一步地在调试器模式下运行代码,最后出现错误。如果有人能帮助我,我将非常感激。
#include <stdlib.h>
#include <stdio.h>
void realocare(int **v, int n,int m)
{
int *aux;
unsigned int i;
aux = (int*)malloc(m*sizeof(int));
for (i = 0; i < m; i++)
aux[i] = v[i];
*v = (int*)malloc(n*sizeof(int));
for (i = 0; i < m; i++)
v[i] = aux[i];
free(aux);
}
void afisare(int *v, int n,int i)
{
for (i = 0; i < n; i++)
printf_s("%d ", v[i]);
printf_s("\n");
}
int main()
{
int *v;
unsigned int n,i,m;
scanf_s("%u", &n);
v = (int*)malloc(n*sizeof(int));
for (i = 0; i < n; i++)
scanf_s("%d", &v[i]);
m = n;
printf("%d", m);
afisare(v, n, i);
n++;
realocare(&v, n,m);
v[n - 1] = 9000;
afisare(v, n, i);
free(v);
return 0;
}
答案 0 :(得分:2)
您已分配到v
n
元素
v = ... malloc(n*sizeof(int));
并指定m
for (i = 0; i < m; i++)
v[i] = aux[i];
对于m
大于n
的情况:这样做会写入无效内存,并且会调用未定义的行为,因此从此刻开始就会发生任何事情。
在您的微粒案例中,很可能会混淆内部内存管理结构,导致失败后来调用free()
。
对传递给函数的变量所做的更改不被调用者反映,因为C中的函数始终只是接收到调用者传递的内容的副本。
因此,例如,您分配给v
的新值会将 unknown 保留给realocare()
的来电者。
您可以通过调整代码来解决此问题:
void realocare(int **ppv, int n, int m) //reallocation simulation function
{
int *aux;
unsigned int i;
aux = malloc(m*sizeof(int));
for (i = 0; i < m; i++)
aux[i] = (*ppv)[i];
free(*ppv); // Free what you had, to not leak this memory.
*ppv = malloc(n*sizeof(int));
for (i = 0; i < m; i++)
(*ppv)[i] = aux[i];
free(aux);
}
并称之为:
realocare(&v, n, m);
您的代码使用了两次拨打malloc()
和两次拨打free()
。这是低效的。
请看以下内容(添加其他一些不仅仅是化妆品更改):
void realocare(int **ppv, size_t n, size_t m) // no need for negative sizes ...
{
int * aux = malloc(n * sizeof *aux);
size_t i = 0; // no need for negative counters ...
for (;i < m; ++i)
{
aux[i] = (*ppv)[i];
}
free(*ppv);
*ppv = aux;
}
只有一个malloc
和一个free
...: - )
为了完整性,一个强大的版本:
int realocare(int **ppv, size_t n, size_t m)
{
int result = -1; // be pessimistic
if (NULL == ppv)
{
errno = EINVAL;
}
else
{
int * aux = malloc(n * sizeof *aux);
if (NULL != aux)
{
size_t i = 0;
for (;i < m; ++i)
{
aux[i] = (*ppv)[i];
}
free(*ppv);
*ppv = aux;
result = 0; // return success!
}
}
return result;
}
这样称呼:
#include <stdlib.h>
#include <stdio.h>
#include <errno.h> // for errno
...
int main(void)
{
...
if (-1 == realocare(&v, n, m))
{
perror("realocare() failed");
exit(EXIT_FAILURE);
}