在 malloc 之后检查 &在调用 free() 之前

Check after malloc & before calling free()

本文关键字:之前 free malloc 之后 检查 调用      更新时间:2023-10-16

我已经阅读了这篇关于在调用free((之前检查的文章。我想通过一个案例进一步确认。

以下代码是从我的C++项目中复制的(经过测试,没有错误/警告(。我只想确认在C++中检查内存分配free((的正确方法。

// part 1: declare 
typedef struct cipher_params_t {
unsigned char * p1;     
int p2;                 
}cipher_params_t;
// part 2: allocate memory
cipher_params_t *params = (cipher_params_t*)malloc(sizeof(cipher_params_t));
// part 3: check allocate memory
if (!params) {
/* Unable to allocate memory on heap*/
fprintf(stderr, "ERROR: malloc error: %sn", strerror(errno));
return errno;
}
// part 4: assign values
unsigned char key[16] = {0x01, 0x02, ..., 0x0f};
params -> p1 = key;
params -> p2 = 1;
// part 5: use params for some function
some_func(params);
// part 6: free params lastly
cleanup1(params);
// cleanup2(params); //another option
void cleanup1 (cipher_params_t *params){
if(params) free(params)
}
void cleanup2 (cipher_params_t *params){
if(params!=NULL) free(params)
}

问题:

  1. 在第 3 部分中,这是检查 if(!params( 的正确方法吗?这里不考虑任何错误?

  2. 在第 6 部分中,我给出了 2 个选项 - if(params( 和 if(params!=NULL(。它们是一样的吗?

  3. 在第 1 部分中,结构包括指针 (p1( 和非指针 (p2(。释放指针、释放非指针和释放两者的组合有什么区别?

  4. 如果我使用 delete[ ] 而不是 free((。如何?有什么区别?

在第 3 部分中,这是检查 if(!params( 的正确方法吗?这里不考虑任何错误?

是的,这是正确的,因为malloc()失败时返回 NULL。

在第 6 部分中,我给出了 2 个选项 - if(params( 和 if(params!=NULL(。它们是一样的吗?

是的,它们是相同的。但是在C++有几个原因使用nullptr(正确的类型nullptr_t(而不是NULL。

在第 1 部分中,结构包括指针 (p1( 和非指针 (p2(。释放指针、释放非指针和释放两者的组合有什么区别?

事实上,您不会也不能释放非指针。在您的情况下,您只释放一个指针,该指针是指向cipher_params_t结构的指针。
使用malloc(),您可以分配内存以包含cipher_params_t无论内容是什么,您只需分配足够的空间来包含它。当你free()时,你会释放分配的内存,无论结构包含什么。
请注意,malloc()free()不调用构造函数/析构函数,无论是对于尖头结构还是其内容。它们只是保留/分配内存空间。

如果我使用 delete[ ] 而不是 free((。如何?有什么区别?

永远不要混合malloc()/free()new/deletenew[]/delete[],因为它们不做同样的事情。您应该阅读new/delete和malloc/free有什么区别?了解更多信息。

关于这个问题:

在第 1 部分中,结构包括指针 (p1( 和非指针 (p2(。什么 释放指针、释放非指针和释放指针之间的区别 两者的结合?

在您给出的示例中,您正在从堆内存中删除一个结构。此结构有一个指针(假设为 8 个字节(和一个 int(通常为 4 个字节(,因此您可以删除这段内存(12 个字节(,而不会删除其他任何内容。

指针指向的内存将保留在那里,因此不会触摸键[16]。在您的示例中可能存在一个问题,因为参数在堆上并且键在堆栈中,当您离开范围时堆栈将被删除,但参数指针仍然可以指向它。