【问题标题】:Check after malloc & before calling free()在 malloc 之后和调用 free() 之前检查
【发布时间】:2019-09-30 08:13:27
【问题描述】:

在调用 free() 之前,我已阅读 this 关于检查的帖子。我想通过一个案例进一步确认。

以下代码是从我的 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: %s\n", 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()。如何?有什么区别?

【问题讨论】:

  • 在 C++ 中,您几乎应该从不使用mallocfree。如果您需要使用动态分配对象,请尝试使用the standard C++ smart pointers。或者使用new 创建对象并使用delete 释放它们。
  • @:我应该用什么?
  • 这看起来更像 C,你没有使用任何 C++ 特性
  • 还要注意freedelete都处理空指针,之前不需要检查。
  • 编写该测试的正确方法是不要这样做。不需要。

标签: c++ error-handling free


【解决方案1】:

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

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

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

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

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

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

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

永远不要混用 malloc()/free()new/deletenew[]/delete[],因为它们不会做同样的事情。您应该阅读What is the difference between new/delete and malloc/free? 了解更多信息。

【讨论】:

  • 我读了你的链接。所以 malloc() 后面不能跟 delete/delete[ ]?因为一个是原始内存,另一个是析构函数。但是这里geeksforgeeks.org/delete-in-c 展示了一个“删除malloc 动态分配的内存”的例子。为什么?
  • @TJCLARK • 混合它们是未定义的行为。在我的平台上,混合它们会终止应用程序。
  • @TJCLARK 这是一个完美的例子,它表明像 geeksforgeeks 这样的网站是不可信的。混合它们是未定义的行为。它可能会意外地做我们想要的,或者......任何事情都可能发生。事实上,功能的表格比较(在我提供的链接中)明确说明了为什么绝不能混合使用它们。
【解决方案2】:

关于问题:

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

在您提供的示例中,您正在从堆内存中删除一个结构。这个结构有一个指针(假设 8 个字节)和一个 int(通常是 4 个字节),所以你删除了这块内存(12 个字节),没有别的了。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-16
    • 1970-01-01
    • 2012-07-15
    • 2021-05-24
    • 2014-02-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多