在C中执行free()的正确方法

在C中执行free()的正确方法,c,malloc,free,C,Malloc,Free,我有以下代码,其中包含一个struct数组。每个数组元素都有一个字符串的副本。我的问题是,在所有事情都完成之后,什么是做free()的正确方法: 1 #include <string.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 5 typedef struct testStruct { 6 char *val; 7 int index; 8 }

我有以下代码,其中包含一个struct数组。每个数组元素都有一个字符串的副本。我的问题是,在所有事情都完成之后,什么是做free()的正确方法:

  1 #include <string.h>
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4
  5 typedef struct testStruct {
  6         char *val;
  7         int index;
  8 } testStruct;
  9
 10
 11 int main()
 12 {
 13         char *value = "hello world";
 14         int NMAX = 10;
 15         testStruct *test_array = (testStruct *) malloc(NMAX * sizeof(testStruct));
 16
 17         int i;
 18         for (i = 0; i < NMAX; i++)
 19         {
 20                 test_array[i].val = strdup(value);
 21                 test_array[i].index = i;
 22
 23                 printf("added %d \n", i);
 24         }
 25
 26         for (i = 0; i < NMAX; i++)
 27         {
 28 //              free(test_array[i].val);  /* is it okay not to free the val field? */
 29         }
 30         free(test_array);         /* only do this free() on the entire array */
 31
 32 }
1#包括
2#包括
3#包括
4.
5类型定义结构testStruct{
6个字符*val;
7整数指数;
8}testStruct;
9
10
11 int main()
12 {
13 char*value=“你好世界”;
14 int NMAX=10;
15 testStruct*test_数组=(testStruct*)malloc(NMAX*sizeof(testStruct));
16
17国际一级;
18表示(i=0;i

分配给每个“val”的内存是否会在执行结束时释放?

您需要释放
val
字段,因为它会生成动态分配的字符串的新副本

为了避免许多堆分配,如果字符串长度有上限,则无需使用
strdup
。只需在结构本身内部声明一个静态字符数组:

const size_t MAX_LENGTH = 32;

typedef struct TestStruct
{
  char val[MAX_LENGTH];
  ..
}
并使用
strncpy
复制内容


此外,不需要将malloc返回的指针强制转换为指定的类型,因为在C中,
void*
可以转换为其他类型,而无需显式向下转换(在C++中不是这样的)。

您需要释放
val
字段,因为它会生成动态分配的字符串的新副本

为了避免许多堆分配,如果字符串长度有上限,则无需使用
strdup
。只需在结构本身内部声明一个静态字符数组:

const size_t MAX_LENGTH = 32;

typedef struct TestStruct
{
  char val[MAX_LENGTH];
  ..
}
并使用
strncpy
复制内容


此外,不需要将malloc返回的指针强制转换为指定的类型,因为在C中,void*
可以转换为其他类型,而无需显式向下转换(在C++中不是这样的)。

请记住,一旦释放了指针(地址),就无法通过该地址访问内存。strdup()为每个
test_数组[i].val分配内存(并复制字符串),因此首先在循环中释放它,然后释放
test_数组

for (i = 0; i < NMAX; i++)
{
     free(test_array[i].val); // free memory allocated by `strdup(value);`
}
free(test_array); // free by malloc() @ line number 15
(i=0;i { 空闲(test_array[i].val);//由'strdup(value)分配的空闲内存` } 免费(测试_数组);//malloc()释放@行号15

这类似于内存分配步骤的相反顺序

记住,一旦释放了指针(地址),就不能通过该地址访问内存。strdup()为每个
test_数组[i].val分配内存(并复制字符串),因此首先在循环中释放它,然后释放
test_数组

for (i = 0; i < NMAX; i++)
{
     free(test_array[i].val); // free memory allocated by `strdup(value);`
}
free(test_array); // free by malloc() @ line number 15
(i=0;i { 空闲(test_array[i].val);//由'strdup(value)分配的空闲内存` } 免费(测试_数组);//malloc()释放@行号15

这类似于内存分配步骤的相反顺序

所有内存总是在执行结束时释放——除了极少数非常“特殊”的非常用系统(如果您正在使用,您会知道;如果有疑问,您不会)。但是,在退出之前释放所有内存是一种很好的做法。对于长时间运行的进程,不泄漏内存是至关重要的。短暂的玩具程序是一回事;你可以逍遥法外。长寿命的主程序完全是另一回事。所有内存总是在执行结束时释放——除了极少数不常用的非常“特殊”的系统(你会知道你是否在使用一个;如果有疑问,你不会)。但是,在退出之前释放所有内存是一种很好的做法。对于长时间运行的进程,不泄漏内存是至关重要的。短暂的玩具程序是一回事;你可以逍遥法外。长期的主要项目是另一回事。