唯一指针的记忆集

时间:2019-06-26 10:05:26

标签: c++ smart-pointers

我正在将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 ++编写并考虑使用智能指针呢?我的转换正确吗?

2 个答案:

答案 0 :(得分:3)

  

我跳过了第一个memset,因为我认为智能指针不再需要它。

您是正确的,不需要使用它,但是使用std::make_unique会特别需要它,原因是使用std::memset可以初始化数组。不是因为您使用的是智能指针。那是假设首先需要初始化。事实并非如此,因为内容即将填充到函数中。

要考虑到std::memcpyMatrix仅在类型(在这种情况下为std::fill_n)是可复制的情况下才能正确运行。如果不是这种情况,则必须分别使用std::fill(或std::copy)和std::memset。如果类型也可以复制,则可以使用该方法,因此您在任何情况下都可以使用它们。

  

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

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

  

那么我该如何用C ++编写并考虑使用智能指针呢?

您可以std::memset(matrix.get(), 0, 256*sizeof(decltype(*matrix))); 这样的由智能指针指向的数组:

std::fill_n

或改为使用std::fill_n(matrix.get(), 256, MATRIX{});

MATRIX* matrix = NULL;
  

我的想法是,因为它是std::vector,所以我应该使用智能指针。

std::vector是一个RAII容器,代表一个动态数组。您正在动态分配一个数组。 if (TextUtils.isEmpty(string)) return ""; final int lastPos = string.length() - 1; if (lastPos < 0 || (string.charAt(0) == '"' && string.charAt(lastPos) == '"')) return string; return "\"" + string + "\""; 是合适的。

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

答案 1 :(得分:1)

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