使用free()

时间:2016-12-02 15:18:54

标签: c dynamic malloc free dynamic-allocation

我是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;
}

1 个答案:

答案 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);
  }