使用 free() 时堆损坏
heap corruption when using free()
我是 c 中动态分配的新手,在调用 free()
函数时出现堆损坏错误。
整个代码应该模拟重新分配函数realloc()
并且直到最后它都可以正常工作。我运行 代码在debugger模式下一步步重复多次,最后出现错误。如果有人可以帮助我,我将不胜感激。
#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;
}
您分配给 v
n
个元素
v = ... malloc(n*sizeof(int));
并分配 m
for (i = 0; i < m; i++)
v[i] = aux[i];
对于 m
大于 n
的情况:这样做会写入无效内存,并由此调用未定义的行为,因此从这一刻起任何事情都可能发生。
在您的特殊情况下,这很可能会扰乱内部内存管理结构,导致稍后调用 free()
.
失败
对已传递给函数的变量所做的更改不会由调用者反映,因为 C 中的函数始终只接收调用者的副本流传下来。
因此,例如,您分配给 v
的新值对于 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);
}
我是 c 中动态分配的新手,在调用 free()
函数时出现堆损坏错误。
整个代码应该模拟重新分配函数realloc()
并且直到最后它都可以正常工作。我运行 代码在debugger模式下一步步重复多次,最后出现错误。如果有人可以帮助我,我将不胜感激。
#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;
}
您分配给 v
n
个元素
v = ... malloc(n*sizeof(int));
并分配 m
for (i = 0; i < m; i++)
v[i] = aux[i];
对于 m
大于 n
的情况:这样做会写入无效内存,并由此调用未定义的行为,因此从这一刻起任何事情都可能发生。
在您的特殊情况下,这很可能会扰乱内部内存管理结构,导致稍后调用 free()
.
对已传递给函数的变量所做的更改不会由调用者反映,因为 C 中的函数始终只接收调用者的副本流传下来。
因此,例如,您分配给 v
的新值对于 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);
}