如何在 unique_ptr 中使用 memcpy
how to use memcpy with unique_ptr
当我遇到这个时,我正在尝试学习智能指针。
{ //Example 1
//String to be copied
std::string strHello = "HelloWorld1";
int size = strHello.length();
//Creating Ptr using make_unique
std::unique_ptr<char[]> pstrText;
pstrText = make_unique<char[]>(size + 1); // Allocating +1 for [=11=]
//Copying values to the new pointer
int r = memcpy_s(pstrText.get(), size + 1, strHello.c_str(), size);
//Printing
std::cout << pstrText.get() << std::endl;
}
{ //Example 2
//String to be copied
std::string strHello = "HelloWorld2";
int size = strHello.length();
//Creating Ptr using make_unique
std::unique_ptr<char[]> pstrText;
pstrText = make_unique<char[]>(size);
//Copying values to the new pointer
int r = memcpy_s(pstrText.get(), size, strHello.c_str(), size);
//Printing
std::cout << pstrText.get() << std::endl;
}
{//Example 3
//String to be copied
std::string strHello = "HelloWorld3";
int size = strHello.length();
//Creating Ptr using make_unique
std::unique_ptr<char[]> pstrText;
pstrText = make_unique<char[]>(size + 1); //Allocating + 1
//Copying values to the new pointer
int r = memcpy_s(pstrText.get(), size, strHello.c_str(), size);
//Printing
std::cout << pstrText.get() << std::endl;
}
{//Example 4
//String to be copied
std::string strHello = "HelloWorld4";
int size = strHello.length();
//Creating Ptr using make_unique
std::unique_ptr<char[]> pstrText;
pstrText = make_unique<char[]>(size);
//Copying values to the new pointer
int r = memcpy_s(pstrText.get(), size + 1, strHello.c_str(), size);
//Printing
std::cout << pstrText.get() << std::endl;
}
使用 VS 2013 Debug(Win32) 的输出如下:
HelloWorld1
HelloWorld2²²²²½½½½½½½½■
HelloWorld3
HelloWorld4²²²²½½½½½½½½■
- 如果示例 1 是正确的,为什么示例 3 也给出了正确的输出?
- 末尾的垃圾值表示什么?
- 为什么编译器没有抛出任何错误或异常?
- 在示例4中,为什么我们尝试在最后复制一个值但没有初始化时没有错误
- 在这种情况下,我们如何正确初始化智能指针?如果它是 BYTE 数组而不是 char,会有什么变化吗?
你需要知道的两件事:
首先是在 C++ 中 memcpy_s
是 Microsoft VC++ CRT 特定的扩展。它存在于 C 中(添加到 C11 标准中),但即便如此,Microsoft 对安全功能的实现也常常不遵循 C 标准。
第二件事,也是导致问题的原因,是最后一个参数是要复制的字节数。由于您只在此处指定 size
,因此您的调用不会复制字符串空终止符。您需要复制 size + 1
个字节:
int r = memcpy_s(pstrText.get(), size + 1, strHello.c_str(), size + 1);
// ^^^^
// Copy plus one, to also copy the null-terminator
If Example 1 is correct why does the Example 3 also give the correct output?
make_unique<char[]>(size + 1);
将所有 char
初始化为 0。示例 1 和示例 3 都不会覆盖它,因为它们分别复制了 size + 1
和 [=13= 中较小的一个]; size
和 size
中较小的一个。 IE。他们都复制 size
char
s
What Does the garbage values at the end signify?
你的程序有未定义的行为。 std::ostream::operator<<(char *)
在这种情况下 读取字节直到它看到 0。
Why didn't the compiler throw any error or exception?
因为C++不安全。 整个程序 不受 C++ 规则的约束,而不是在访问数组外部时定义特定行为(例如抛出异常)。这叫做"Undefined Behaviour".
In Example 4 Why is there no error when we had tried to copy a value at the end but was not initialized
因为 C++ 不安全
How do we properly initialize a smart pointer in this case? Will anything change if it a BYTE array instead of char;
例子1和例子3都可以。但是,为什么不直接使用 std::string
?
当我遇到这个时,我正在尝试学习智能指针。
{ //Example 1
//String to be copied
std::string strHello = "HelloWorld1";
int size = strHello.length();
//Creating Ptr using make_unique
std::unique_ptr<char[]> pstrText;
pstrText = make_unique<char[]>(size + 1); // Allocating +1 for [=11=]
//Copying values to the new pointer
int r = memcpy_s(pstrText.get(), size + 1, strHello.c_str(), size);
//Printing
std::cout << pstrText.get() << std::endl;
}
{ //Example 2
//String to be copied
std::string strHello = "HelloWorld2";
int size = strHello.length();
//Creating Ptr using make_unique
std::unique_ptr<char[]> pstrText;
pstrText = make_unique<char[]>(size);
//Copying values to the new pointer
int r = memcpy_s(pstrText.get(), size, strHello.c_str(), size);
//Printing
std::cout << pstrText.get() << std::endl;
}
{//Example 3
//String to be copied
std::string strHello = "HelloWorld3";
int size = strHello.length();
//Creating Ptr using make_unique
std::unique_ptr<char[]> pstrText;
pstrText = make_unique<char[]>(size + 1); //Allocating + 1
//Copying values to the new pointer
int r = memcpy_s(pstrText.get(), size, strHello.c_str(), size);
//Printing
std::cout << pstrText.get() << std::endl;
}
{//Example 4
//String to be copied
std::string strHello = "HelloWorld4";
int size = strHello.length();
//Creating Ptr using make_unique
std::unique_ptr<char[]> pstrText;
pstrText = make_unique<char[]>(size);
//Copying values to the new pointer
int r = memcpy_s(pstrText.get(), size + 1, strHello.c_str(), size);
//Printing
std::cout << pstrText.get() << std::endl;
}
使用 VS 2013 Debug(Win32) 的输出如下:
HelloWorld1 HelloWorld2²²²²½½½½½½½½■ HelloWorld3 HelloWorld4²²²²½½½½½½½½■
- 如果示例 1 是正确的,为什么示例 3 也给出了正确的输出?
- 末尾的垃圾值表示什么?
- 为什么编译器没有抛出任何错误或异常?
- 在示例4中,为什么我们尝试在最后复制一个值但没有初始化时没有错误
- 在这种情况下,我们如何正确初始化智能指针?如果它是 BYTE 数组而不是 char,会有什么变化吗?
你需要知道的两件事:
首先是在 C++ 中 memcpy_s
是 Microsoft VC++ CRT 特定的扩展。它存在于 C 中(添加到 C11 标准中),但即便如此,Microsoft 对安全功能的实现也常常不遵循 C 标准。
第二件事,也是导致问题的原因,是最后一个参数是要复制的字节数。由于您只在此处指定 size
,因此您的调用不会复制字符串空终止符。您需要复制 size + 1
个字节:
int r = memcpy_s(pstrText.get(), size + 1, strHello.c_str(), size + 1);
// ^^^^
// Copy plus one, to also copy the null-terminator
If Example 1 is correct why does the Example 3 also give the correct output?
make_unique<char[]>(size + 1);
将所有 char
初始化为 0。示例 1 和示例 3 都不会覆盖它,因为它们分别复制了 size + 1
和 [=13= 中较小的一个]; size
和 size
中较小的一个。 IE。他们都复制 size
char
s
What Does the garbage values at the end signify?
你的程序有未定义的行为。 std::ostream::operator<<(char *)
在这种情况下 读取字节直到它看到 0。
Why didn't the compiler throw any error or exception?
因为C++不安全。 整个程序 不受 C++ 规则的约束,而不是在访问数组外部时定义特定行为(例如抛出异常)。这叫做"Undefined Behaviour".
In Example 4 Why is there no error when we had tried to copy a value at the end but was not initialized
因为 C++ 不安全
How do we properly initialize a smart pointer in this case? Will anything change if it a BYTE array instead of char;
例子1和例子3都可以。但是,为什么不直接使用 std::string
?