唯一指针的 Memset
Memset for Unique 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++ 编写它并考虑到我使用的是智能指针呢?我上面的转换正确吗?
- 使用
vector<MATRIX>
可以解决很多问题。
new
不会 return 为 null,但会抛出。因此,空检查无效(除非使用 nothrow
)。
- 您将原始指针方法与更新的 smart-pointer、基于矢量的方法混合在一起。您不应该在最新的 C++ 代码中使用任何原始内存操作函数。
- 相反,在
MATRIX
class 中有一个构造函数,它将初始化 MATRIX
的所有成员。您可以有(或 prevent)copy/move constructors/assignment 运算符。考虑将 =default
和 =delete
与特殊成员函数一起使用。
memcpy
等可能会破坏 MATRIX
类型中某些 non-POD 成员的状态(如 std::string
、std::vector
)。这样的 undefined-behaviours 很难检测到,因此不要使用任何 mem* 函数。
I skipped the first memset
since I believe I do not need it anymore for smart pointers.
你是对的,不需要它,但是你使用 std::make_unique
不需要它的具体原因是,哪个值初始化数组;不是因为您使用的是智能指针。这是假设首先需要初始化。好像不是这样的,因为内容即将在一个函数中被填充。
请注意 std::memset
和 std::memcpy
仅当类型(在本例中为 Matrix
)可简单复制时才会正确运行。如果不是这种情况,则必须分别使用 std::fill_n
(或 std::fill
)和 std::copy
。如果该类型也可以简单复制,则可以使用它,因此在任何情况下您都可以使用它们。
But the second memset I believe is needed (since new values will be saved).
与第一个 std::memset
类似,不清楚为什么您认为需要第二个 std::memset
(无论是在 C 还是 C++ 中)。如果要将新值写入数组,那么 std::memset
有什么影响?
So how do I write that in C++ and considering that I am using a smart pointer?
您可以 std::memset
一个由智能指针指向的数组,如下所示:
std::memset(matrix.get(), 0, 256*sizeof(decltype(*matrix)));
或使用 std::fill_n
代替:
std::fill_n(matrix.get(), 256, MATRIX{});
Hmm my thought was since it was MATRIX* matrix = NULL;
then I should use a smart pointer.
std::vector
是代表动态数组的RAII容器。您正在动态分配一个数组。 std::vector
合适。
将 C 转换为 C++ 不仅仅是用智能指针替换裸拥有指针。另一件事是用标准库提供的标准数据结构和算法替换自定义 re-implementations。
我正在将 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++ 编写它并考虑到我使用的是智能指针呢?我上面的转换正确吗?
- 使用
vector<MATRIX>
可以解决很多问题。 new
不会 return 为 null,但会抛出。因此,空检查无效(除非使用nothrow
)。- 您将原始指针方法与更新的 smart-pointer、基于矢量的方法混合在一起。您不应该在最新的 C++ 代码中使用任何原始内存操作函数。
- 相反,在
MATRIX
class 中有一个构造函数,它将初始化MATRIX
的所有成员。您可以有(或 prevent)copy/move constructors/assignment 运算符。考虑将=default
和=delete
与特殊成员函数一起使用。 memcpy
等可能会破坏MATRIX
类型中某些 non-POD 成员的状态(如std::string
、std::vector
)。这样的 undefined-behaviours 很难检测到,因此不要使用任何 mem* 函数。
I skipped the first
memset
since I believe I do not need it anymore for smart pointers.
你是对的,不需要它,但是你使用 std::make_unique
不需要它的具体原因是,哪个值初始化数组;不是因为您使用的是智能指针。这是假设首先需要初始化。好像不是这样的,因为内容即将在一个函数中被填充。
请注意 std::memset
和 std::memcpy
仅当类型(在本例中为 Matrix
)可简单复制时才会正确运行。如果不是这种情况,则必须分别使用 std::fill_n
(或 std::fill
)和 std::copy
。如果该类型也可以简单复制,则可以使用它,因此在任何情况下您都可以使用它们。
But the second memset I believe is needed (since new values will be saved).
与第一个 std::memset
类似,不清楚为什么您认为需要第二个 std::memset
(无论是在 C 还是 C++ 中)。如果要将新值写入数组,那么 std::memset
有什么影响?
So how do I write that in C++ and considering that I am using a smart pointer?
您可以 std::memset
一个由智能指针指向的数组,如下所示:
std::memset(matrix.get(), 0, 256*sizeof(decltype(*matrix)));
或使用 std::fill_n
代替:
std::fill_n(matrix.get(), 256, MATRIX{});
Hmm my thought was since it was
MATRIX* matrix = NULL;
then I should use a smart pointer.
std::vector
是代表动态数组的RAII容器。您正在动态分配一个数组。 std::vector
合适。
将 C 转换为 C++ 不仅仅是用智能指针替换裸拥有指针。另一件事是用标准库提供的标准数据结构和算法替换自定义 re-implementations。