如何使用 malloc() 将 C 语句转换为 C++



>我在 C 中有一个带有此代码的缓冲区

    buffer = malloc(sizeof(uint32_t)*CACHE_LEN*2);

如何将此行更改为C++?

malloc好还是new[]好?
我无法理解这个sizeof(uint32_t)的含义.

你提到的那行在C++中编译得很好,除了如果buffer不是void *,那么你可能需要在C++中强制转换malloc的返回值,这在 C 中不需要(可能不应该这样做)。

例如:

uint32_t *buffer = (uint32_t *) malloc(sizeof(uint32_t)*CACHE_LEN*2);

但是,您可能希望转换为new/delete范式;这需要的不仅仅是改变这条线。

例如:

uint32_t *buffer = new uint32_t[CACHE_LEN*2];
...
delete[] buffer;

如果你想更像C++,那就使用std::vector或类似的东西:

std::vector<uint32_t> buffer(CACHE_LEN*2);

假设CACHE_LEN确实是一个宏,它隐藏了编译时已知的值:

auto buffer = make_unique<array<uint32_t, CACHE_LEN*2>>();

这有一个有趣的特性,您可以在几乎零开销的情况下获得现代C++的几乎所有优势。

如果您希望更接近您的 C 根目录,或者在编译时不知道CACHE_LEN,则可以使用,这会删除array提供的一些功能:

auto buffer = make_unique<uint32_t[]>(CACHE_LEN*2);

最后,如果你想走另一条路,你可以使用一个完全动态的数组(vector C++术语):

auto buffer = std::vector<uint32_t>(CACHE_LEN*2);

上述所有解决方案都确保资源管理按buffer范围完成。使用make_unique的解决方案可以很容易地(或多或少)更改为使用共享指针。

为了保持完全老派,std::mallocstd::free也存在于C++中,但malloc需要将其结果转换为正确的指针类型。它们也可以替换为 new uint32_t[CACHE_LEN*2]delete[] buffer .

附言:sizeof(uint32_t)的含义只是为了解释这样一个事实,即malloc不分配多个元素,而是分配多个字节 - 并且大多数类型需要每个元素超过 1 个字节。

std::vector<uint32_t> v(CACHE_LEN * 2);

sizeof(type)返回传递的表达式类型的大小(以字符为单位)。对于uint32_t,它将是4。

sizeof() 给出了括号之间给定类型的字节大小。该类型在内存中占用 sizeof()。当您分配内存以存储数据时,您需要知道这一点。CACHE_LEN * 2完全取决于您的使用情况。

如果您需要存储五次一对uint32_t,请使用:

malloc( sizeof( uint32_t ) * 2 * 5 );

malloc将分配固定大小的内存。这意味着您无法更改大小。

new/delete 等同于 malloc/free,但C++。如果你使用new[],你也应该使用delete[]。

char buf = new char[ 10 ];
delete[] buf;

delete[] 位于已分配内存的生命周期结束的位置。如果你在函数中创建它,那么 delete[] 也应该在那里。或者你会得到内存泄漏。如果将其放在类的全局范围内,并且在构造函数中分配内存,则假设删除析构函数中的内存[],但通常是这种情况。这取决于为什么以及何时需要内存。有一件事是肯定的,如果你分配,你需要释放(new[]/delete[])。

Paolo Bolzoni 提到了 std::vector 的使用

这很好,在大多数情况下非常易于使用。如果您需要优化代码以提高速度,那么拥有固定大小的内存块会比 std::vector 更快。这取决于您的需求,也取决于您的喜好。

buffer = malloc(sizeof(uint32_t)*CACHE_LEN*2);

这可以通过多种方式C++"翻译"。

但是,首先必须清楚这在 C 中的作用,因为您在问题中写道,您不清楚sizeof(uint32_t)的含义。

使用 malloc() ,您可以动态(即在运行时)从中分配一些连续的空间。
传递给malloc的参数是请求的空间的大小以字节为单位)。
您发布的代码似乎分配了CACHE_LEN*2 uint32_t元素的数量。由于malloc期望其大小参数以字节为单位,因此您必须将CACHE_LEN*2"count"因子)乘以每个元素的大小(以字节为单位),即sizeof(uint32_t) uint32_t的大小。

因此,您有:

  • 元素类型:uint32_t
  • 元素数:CACHE_LEN*2
  • 每个元素的大小(以字节为单位):sizeof(uint32_t)

所以:

malloc() = sizeof(uint32_t) * CACHE_LEN*2 的总大小(以字节为单位)

现在这个malloc()调用应该很清楚,让我们继续讨论C++等效项。


最直接的"映射"是从C的malloc()到C++的new[]

请注意,虽然malloc要求大小以字节表示,但当您调用new[]时,您可以只指定元素计数而不是原始字节计数)。

因此,使用 new[] 的C++代码将是这样的:

// Allocate (CACHE_LEN*2) elements of type uint32_t
uint32_t* buffer = new uint32_t[CACHE_LEN*2];

当您使用 malloc() 分配内存时,您必须使用 free() 释放它。
new[]的C++对应物是delete[],例如:

// Release buffer memory allocated with new[]
delete[] buffer;
// Avoid dangling references
buffer = nullptr;

但还有更多。当内存分配失败时,malloc只返回NULL。相反,C++ 的 new[] 会在分配失败时引发异常。此例外的类型为 std::bad_alloc 。您可以在代码中捕获某些内容以处理内存分配失败的情况。

如果你想要一个类似于malloc的行为,失败的分配返回一个nullptr指针,你可以将std::nothrow常量与new[]一起使用,例如:

buffer = new (std::nothrow) uint32_t[CACHE_LEN*2];
// On allocation failure, just returns nullptr
// (does *not* throw an exception).

但是,在新式C++代码中,您可能希望使用方便的容器类来存储连续的缓冲区内存。一个非常常见的候选人是 std::vector .

std::vector是一个类模板:将元素的类型指定为模板参数,并且可以将元素计数指定为构造函数参数,例如:

#include <vector>  // For std::vector 
....
std::vector<uint32_t> buffer(CACHE_LEN*2);

由于 vector 的默认内存分配器使用 new[] 来分配内存,因此在分配失败的情况下,上述构造函数将引发std::bad_alloc C++异常。

请注意,vector分配的内存由向量的析构函数自动释放。因此,您不必手动释放该内存。这有助于编写结构上无法泄漏内存(和其他资源)的代码。

您可以使用其重载operator[]访问向量中的项目,就像普通的简单原始数组一样(例如 buffer[i]访问缓冲区中的第 i 项;请注意,索引是0基于 -的)。

如果你想要一个指向向量开头的指针(严格等价于你的buffer指针),你可以调用vectordata()方法,例如:

// Points to the beginning of vector memory
uint32_t* ptr = buffer.data();
// ...use ptr...

随着C++malloc变得new/new[]free变成delete/delete[]

相关内容

  • 没有找到相关文章

最新更新