唯一指针的内存集

Memset for Unique Pointers

本文关键字:内存 指针 唯一      更新时间:2023-10-16

我正在将C代码转换为C++。

有矩阵指针:

MATRIX* matrix = NULL;
matrix = new MATRIX[256];
if (matrix == NULL)
return FAIL;
memset(matrix, 0, 256*sizeof(MATRIX));

然后用不同的方法填充它:

fillUpMatrix(matrix);

在fillUpMatrix():

memcpy(&matrix[start], &someOtherMatrix[pos], sizeof(MATRIX));

后来,memset被调用为指针,因为它将填充一组不同的值:

memset(matrix, 0, 256*sizeof(MATRIX));

所以我所做的是:

auto matrix= std::make_unique<MATRIX[]>(256);
fillUpMatrix(matrix.get());

我跳过了第一个memset因为我相信我不再需要它来获取智能指针。 但我认为需要第二个memset(因为新值将被保存)。那么我如何在C++中写它并考虑到我正在使用智能指针? 我的上述转换是否正确?

我跳过了第一个memset,因为我相信我不再需要它来获取智能指针。

你是对的,它不是必需的,但不需要它的原因特别在于你使用了std::make_unique,哪个值初始化数组;而不是因为你使用了智能指针。这是假设首先需要初始化。情况似乎并非如此,因为内容即将填充到函数中。

请注意,只有当类型(在本例中为Matrix)是可复制的时,std::memsetstd::memcpy的行为才正确。如果不是这种情况,则必须分别使用std::fill_n(或std::fill)和std::copy。如果类型也是微不足道的可复制的,则可以使用它,因此您在任何情况下都可以使用它们。

但是我认为需要第二个内存集(因为将保存新值)。

与第一个std::memset类似,不清楚为什么你认为需要第二个std::memset(无论是在C还是C++中)。如果要将新值写入数组,那么std::memset有什么影响?

那么我如何在C++中写它并考虑到我正在使用智能指针?

您可以像这样std::memset由智能指针指向的数组:

std::memset(matrix.get(), 0, 256*sizeof(decltype(*matrix)));

或者改用std::fill_n

std::fill_n(matrix.get(), 256, MATRIX{});

嗯,我的想法是既然它MATRIX* matrix = NULL;那么我应该使用一个智能指针。

std::vector是表示动态数组的 RAII 容器。您正在动态分配阵列。std::vector是合适的。

将 C 转换为 C++ 不仅仅是用智能指针替换裸露的指针。另一件事是将典型数据结构和算法的自定义重新实现替换为标准库提供的标准结构和算法。

  • 使用vector<MATRIX>可以解决许多问题。
  • new不返回 null,而是抛出。因此,空检查不起作用(除非使用nothrow)。
  • 您正在将原始指针方法与较新的智能指针、基于矢量的方法混合在一起。不应在最新的C++代码中使用任何原始内存操作函数。
  • 相反,在MATRIX类中有一个构造函数,它将初始化MATRIX的所有成员。您可以拥有(或阻止)复制/移动构造函数/赋值运算符。请考虑将=default=delete与特殊成员函数一起使用。
  • memcpy等可能会破坏MATRIX类型的一些非 POD 成员的状态(如std::stringstd::vector)。这种未定义的行为很难检测到,因此不使用任何mem*函数。