如何为指针的数组正确释放动态分配的内存

时间:2018-12-28 21:06:40

标签: c malloc free

我需要知道我在尝试释放动态分配的内存以用于指向int的指针的数组时是否正确使用了free()

我的代码是从我的一本书中的代码片段修改而来的,并且是一个程序的开始,该程序要求获取三个城市的温度读数。

#include <stdio.h>
#include <stdlib.h>

int main()
{
  int ctr, num, num2 = 0, ctr2 = 0;
  int* temps[3];
  for(ctr = 0; ctr < 3; ctr++)
  {
     puts("how many readings for the city?");
     scanf(" %d", &num);
     temps[ctr] = (int*)malloc(num * sizeof(int));
     num2 += num;
     while(ctr2 < num2)
     {
         puts(" what is reading? ");
         scanf(" %d", &temps[ctr][ctr2]);
         printf("echo: %d ", temps[ctr][ctr2]);

         ctr2++;
     }
  }

  for(ctr = 0; ctr < 3; ctr++)
  {
      free(temps[ctr]);
  }

  getchar();
  getchar();

  return (0);
}

我知道使用malloc()分配了内存的指针可能具有通过循环和数组索引的组合分配和访问的值。因此,我已经使用二维数组的索引从用户输入中分配了值,并且需要知道我是否正确使用了free。我知道这是非常草率的编码,我只是想自由地正确理解以防止任何潜在的内存泄漏。

3 个答案:

答案 0 :(得分:2)

没关系,因为您使用同一条语句尊重相同数量的循环进行分配和释放:

template <template <typename, template <typename...> typename> typename container_type>
void test_int(std::string container_name) {
    container_type<int, std::vector> container1;
    container_type<int, std::set> container2;
    container_type<int, std::list> container3
}

只要确保for(ctr = 0; ctr < 3; ctr++) 可以容纳至少3个元素(这种情况),并且temps不能为零或未定义(测试返回值num和{ {1}})。在这种情况下,可以使用scanf公式来避免对值进行硬编码,这仅是因为您具有指针的 array ,而不是指针的指针。

还避免强制转换返回值num。并使用元素的大小,而不是将其硬编码为sizeof(因此,如果指针的类型发生变化,则大小仍然正确)。分配的改进建议:

malloc

如果在填充数组时破坏了内存,则在调用int时仍可能会遇到分段错误(注释表明确实如此,因为for(ctr = 0; ctr < (int)(sizeof(temps)/sizeof(*temps)); ctr++) { puts("how many readings for the city?"); if (!scanf(" %d", &num) || num <= 0) { printf("wrong number\n"); exit(1); } // or better error handling temps[ctr] = malloc(num * sizeof(*temps[ctr])); 会不断增长)。如果遇到此类错误,请使用valgrind运行代码,或仅执行分配/取消分配(而不执行其余部分)以查找导致问题的代码部分。

答案 1 :(得分:0)

释放动态分配的内存的正确方法是在检查是否已将内存分配到第一位后释放它。由于循环的结构与分配和释放相同,因此如果所有分配均成功,此处将不会有任何问题。因此,我建议您在所有位置检查分配后分配是否成功,并在释放之前检查是否已分配内存。

以下代码将确保所有情况:

scanf(" %d", &num);

/*
 * check here if the value of ctr in non-negative and in the appropriate range
 */

temps[ctr] = (int*)malloc(num * sizeof(int));
if (temps[ctr] == NULL) {
      printf ("Memory allocation failed\n");
      /* 
       * appropriate error handling
       */
}

此外,请检查何时释放内存以确保安全。

for(ctr = 0; ctr < 3; ctr++)
{
      if(temps[ctr]) {
           free(temps[ctr]);
      }
}

您的代码中还有一个错误,即在第一次迭代本身之后,您将获得内存不足的错误,因为变量ctr2从未被初始化。

num2 += num;
while(ctr2 < num2)
 {
     puts(" what is reading? ");
     scanf(" %d", &temps[ctr][ctr2]);
     printf("echo: %d ", temps[ctr][ctr2]);

     ctr2++;
 }

这里,如果num的值在第一次迭代中为20,则在第二次迭代中,您将最终从temps[1][20]开始输入,并假设num的值在第二次迭代为5时,您仅分配了5 * sizeof(int)),因此显然,当您尝试访问temps[1][20]时,您将越界。

答案 2 :(得分:0)

请让我知道以下代码是否可以接受:

#include <stdio.h>
#include <stdlib.h>








int main()
{
  int ctr, num, ctr2 = 0;
  int * temps[3];
  for(ctr = 0; ctr < (int)(sizeof(temps)/sizeof(*temps)); ctr++)
  {
     puts("how many readings for the city?");
 if (!scanf(" %d", &num) || num <= 0) { printf("wrong number\n"); exit(1); }
 temps[ctr] = (int *) malloc(num * sizeof(*temps[ctr]));

     while(ctr2 < num)
     {


     puts(" what is reading? ");
     scanf(" %d", &temps[ctr][ctr2]);
     printf("echo: %d ", temps[ctr][ctr2]);

     ctr2++;
     }
     ctr2 = 0;




  }

  for(ctr = 0; ctr < (int)(sizeof(temps)/sizeof(*temps)); ctr++)
  {
      free(temps[ctr]);
  }

  getchar();
  getchar();

  return (0);


 }