使用语言 c 时在 .h 和 .c 中 malloc 和 free
malloc and free in .h and .c while using language c
我是 C 编程的新手,我对 malloc()
和 free()
感到很困惑。
我需要从文件 (.yaml) 中读取一些随机数的随机数据值并将它们存储在 hashmap 中,类似于 < char *key_name, char *type, void *value >
。
我正在使用 void *
指针来存储我读取为 char *
的任何类型数据,因此我想编写自己的函数来确定数据类型和 return大小合适的指针以将其传递给进一步的任务。
我希望这个函数在我的小解析器(myparser.h 和 myparser.c)中,以便将来将其用作库。
但是!例如,我在 myparser.c 中为读取的每个浮点值执行 中的这段代码:
void *parser_get_pointer(char *token_value, char *type) {
...
else if (strcmp(type, "float") == 0) {
printf("Type float recognized\n");
float *fp = (float *)malloc(sizeof(float));
*fp = atof(token_value);
void *result = (float *)malloc(sizeof(float));
result = fp;
return (float *)result;
}
...
}
主要问题是我应该在哪里 free(fp)
这样我就不会丢失 main.c 中的数据?
不要做两次malloc,会导致内存泄露
完成atof后只需return fp,不需要结果指针。
您可以将 fp 存储在 hashmap 中,并在释放 hashmap 时释放它。
1.You 可能根本不需要 malloc()
。只需使用:
static float f;
if (strcmp(type, "float")==0) {
f = atof(token_value);
return (void *)&f;
}
请注意,由于您的函数 returns (void *)
,调用者将获得值但不知道大小。
您的代码存在内存泄漏;您为 'result' 分配 space,然后当您分配 'result' 内存 space 分配给 'fp' 时 space 丢失(通过 'result = fp'
如果您真的想保持代码不变,那么:
一种。删除行 'void *result = (float *)malloc(sizeof(float));
b.表明函数的调用者必须释放它,即
ptr = (浮动 *)parser_get_pointer(...)
printf("value = %f\n", ptr);
免费(指针);
希望对您有所帮助。
关于malloc()[的一些普遍接受的想法 =47=]、calloc() 和 realloc()函数使用:
1)在使用C时不要强制转换这些函数的return
int *a = (int)malloc(10*sizeof(int)); //wrong
int *a = malloc(10*sizeof(int)); //correct
2) 检查函数
的 return 值
int *a = malloc(10*sizeof(int));
a[0] = 10; //wrong - if malloc failed, a will be NULL.
int *a = malloc(10*sizeof(int));
if(a)
{
a[0] = 10; //correct
3) 在 realloc() 的情况下使用 tmp 变量来避免内存泄漏
tmp = realloc(orig, newsize);
if (tmp == NULL)
{
// could not realloc, but orig still valid
}
else
{
orig = tmp;
}
4) 每次调用 [c] 总是调用一次 free() [m][re]alloc()
int *a = malloc(10*sizeof(int));
if(a)
{
a[0] = 10; //correct
...
free(a);
}
else
{
//handle error
}
不这样做会导致内存泄漏。
让我们解决一些具体问题:
首先,下面的代码是不必要的并且它引入了内存泄漏:
void *result = (float *)malloc(sizeof(float));
result = fp;
您将 malloc
调用的结果分配给 result
,然后立即用 fp
覆盖该值。因此,您丢失了从 malloc
编辑的指针值 return,这意味着您以后将无法 free
该内存。您不需要留出额外的内存来存储指针值。
这段代码的写法,根本不需要result
变量;只是 return fp
。
其次,不要强制转换 malloc
1 的结果 - 根据 C89 标准,它是不必要的,并且在 C89 编译器下,它可以抑制有用的诊断。编写 malloc
调用的最干净的方法是
T *p = malloc( N * sizeof *p ); // for any type T
或
T *p;
...
p = malloc( N * sizeof *p );
表达式 *p
的类型是 T
,因此 sizeof *p
给出与 sizeof (T)
相同的结果。 sizeof
运算符不会尝试评估参数;它不会尝试取消引用 p
。
也不需要强制转换return值;在 C 中,任何指针类型的值都可以转换为 void *
并再次返回,而无需显式强制转换。
至于将 free
调用放在哪里,那将是您决定不再需要存储指向的值的任何地方(例如从哈希图中删除该项目)。那将在您发布的代码之外的某个地方。
1。 C++ 确实 需要强制转换,因为 C++ 不允许 void *
和其他指针类型之间的隐式转换,但如果您使用的是 C++,您就不会乱用 naked无论如何指针。
我是 C 编程的新手,我对 malloc()
和 free()
感到很困惑。
我需要从文件 (.yaml) 中读取一些随机数的随机数据值并将它们存储在 hashmap 中,类似于 < char *key_name, char *type, void *value >
。
我正在使用 void *
指针来存储我读取为 char *
的任何类型数据,因此我想编写自己的函数来确定数据类型和 return大小合适的指针以将其传递给进一步的任务。
我希望这个函数在我的小解析器(myparser.h 和 myparser.c)中,以便将来将其用作库。
但是!例如,我在 myparser.c 中为读取的每个浮点值执行 中的这段代码:
void *parser_get_pointer(char *token_value, char *type) {
...
else if (strcmp(type, "float") == 0) {
printf("Type float recognized\n");
float *fp = (float *)malloc(sizeof(float));
*fp = atof(token_value);
void *result = (float *)malloc(sizeof(float));
result = fp;
return (float *)result;
}
...
}
主要问题是我应该在哪里 free(fp)
这样我就不会丢失 main.c 中的数据?
不要做两次malloc,会导致内存泄露
完成atof后只需return fp,不需要结果指针。
您可以将 fp 存储在 hashmap 中,并在释放 hashmap 时释放它。
1.You 可能根本不需要 malloc()
。只需使用:
static float f;
if (strcmp(type, "float")==0) {
f = atof(token_value);
return (void *)&f;
}
请注意,由于您的函数
returns (void *)
,调用者将获得值但不知道大小。您的代码存在内存泄漏;您为 'result' 分配 space,然后当您分配 'result' 内存 space 分配给 'fp' 时 space 丢失(通过
'result = fp'
如果您真的想保持代码不变,那么: 一种。删除行
'void *result = (float *)malloc(sizeof(float));
b.表明函数的调用者必须释放它,即ptr = (浮动 *)parser_get_pointer(...) printf("value = %f\n", ptr); 免费(指针);
希望对您有所帮助。
关于malloc()[的一些普遍接受的想法 =47=]、calloc() 和 realloc()函数使用:
1)在使用C时不要强制转换这些函数的return
int *a = (int)malloc(10*sizeof(int)); //wrong
int *a = malloc(10*sizeof(int)); //correct
2) 检查函数
的 return 值int *a = malloc(10*sizeof(int));
a[0] = 10; //wrong - if malloc failed, a will be NULL.
int *a = malloc(10*sizeof(int));
if(a)
{
a[0] = 10; //correct
3) 在 realloc() 的情况下使用 tmp 变量来避免内存泄漏
tmp = realloc(orig, newsize);
if (tmp == NULL)
{
// could not realloc, but orig still valid
}
else
{
orig = tmp;
}
4) 每次调用 [c] 总是调用一次 free() [m][re]alloc()
int *a = malloc(10*sizeof(int));
if(a)
{
a[0] = 10; //correct
...
free(a);
}
else
{
//handle error
}
不这样做会导致内存泄漏。
让我们解决一些具体问题:
首先,下面的代码是不必要的并且它引入了内存泄漏:
void *result = (float *)malloc(sizeof(float));
result = fp;
您将 malloc
调用的结果分配给 result
,然后立即用 fp
覆盖该值。因此,您丢失了从 malloc
编辑的指针值 return,这意味着您以后将无法 free
该内存。您不需要留出额外的内存来存储指针值。
这段代码的写法,根本不需要result
变量;只是 return fp
。
其次,不要强制转换 malloc
1 的结果 - 根据 C89 标准,它是不必要的,并且在 C89 编译器下,它可以抑制有用的诊断。编写 malloc
调用的最干净的方法是
T *p = malloc( N * sizeof *p ); // for any type T
或
T *p;
...
p = malloc( N * sizeof *p );
表达式 *p
的类型是 T
,因此 sizeof *p
给出与 sizeof (T)
相同的结果。 sizeof
运算符不会尝试评估参数;它不会尝试取消引用 p
。
也不需要强制转换return值;在 C 中,任何指针类型的值都可以转换为 void *
并再次返回,而无需显式强制转换。
至于将 free
调用放在哪里,那将是您决定不再需要存储指向的值的任何地方(例如从哈希图中删除该项目)。那将在您发布的代码之外的某个地方。
1。 C++ 确实 需要强制转换,因为 C++ 不允许
void *
和其他指针类型之间的隐式转换,但如果您使用的是 C++,您就不会乱用 naked无论如何指针。