Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从ostringstream读取/写入更改原始数据_C++_Ostringstream - Fatal编程技术网

C++ 从ostringstream读取/写入更改原始数据

C++ 从ostringstream读取/写入更改原始数据,c++,ostringstream,C++,Ostringstream,在测试中,我将给定值写入ostringstream。之后,我尝试评估是否写入了正确的值。然而,我在流中写入的原始值似乎在以后从流中读取时发生了更改 我将问题归结为以下代码: #包括 #包括 #包括 int main() { std::ostringstream os; uint16_t数据{123}; 操作系统写入(重新解释强制转换(和数据),大小(uint16_t)); 返回的uint16数据; std::string data_str(os.str()); std::copy(data_st

在测试中,我将给定值写入
ostringstream
。之后,我尝试评估是否写入了正确的值。然而,我在流中写入的原始值似乎在以后从流中读取时发生了更改

我将问题归结为以下代码:

#包括
#包括
#包括
int main()
{
std::ostringstream os;
uint16_t数据{123};
操作系统写入(重新解释强制转换(和数据),大小(uint16_t));
返回的uint16数据;
std::string data_str(os.str());
std::copy(data_str.begin()、data_str.end()、返回的数据);
assert(data==123);//
std::copy()
在这种情况下并不像您想象的那样。它只是一个逻辑循环的包装器,将单个元素从一个容器复制到另一个容器。您实际上是告诉它将两个单独的
字符从
数据str
复制到
uint16\t[2]
array,除了您实际上没有诸如array这样的属性外,因此您有未定义的行为,并且正在破坏堆栈内存

本声明:

std::copy(data_str.begin()、data_str.end()、返回的数据);
基本上是这样做的:

std::string::迭代器iter=data_str.begin(),end=data_str.end();
uint16\u t*dest=&返回的数据;
while(iter!=结束){
*dest++=*iter++;
}
在你的例子中,这基本上就是这样做的等价物:

uint16\u t*dest=&返回的数据;
dest[0]=静态_cast(数据_str[0]);
dest[1]=静态_cast(数据_str[1]);
它将第一个字节分配给整个
uint16\u t
(这就是您看到值更改的原因),然后将第二个字节分配给下一个整个
uint16\u t
(损坏堆栈)

对于您正在尝试的内容,请改用
std::memcpy()
,例如:

std::memcpy(&data_returned, data_str.c_str(), sizeof(data_returned));
否则,如果确实要使用
std::copy()
,则需要确保它知道要将单个字节复制到目标,而不是整个
uint16\t
s,例如:

std::copy(data_str.begin()、data_str.end()、reinterpret_cast(&data_returned));
由于输入和输出都是琐碎的类型,因此应该将其优化为适当的
std::memcpy()
-等效副本。

std::copy()
在这种情况下并不像您想象的那样。它只是一个逻辑循环的包装器,将单个元素从一个容器复制到另一个容器。您实际上是告诉它从
data\u str
复制两个单独的
字符到
uint16\t[2]
array,除了您实际上没有诸如array这样的属性外,因此您有未定义的行为,并且正在破坏堆栈内存

本声明:

std::copy(data_str.begin()、data_str.end()、返回的数据);
基本上是这样做的:

std::string::迭代器iter=data_str.begin(),end=data_str.end();
uint16\u t*dest=&返回的数据;
while(iter!=结束){
*dest++=*iter++;
}
在你的例子中,这基本上就是这样做的等价物:

uint16\u t*dest=&返回的数据;
dest[0]=静态_cast(数据_str[0]);
dest[1]=静态_cast(数据_str[1]);
它将第一个字节分配给整个
uint16\u t
(这就是您看到值更改的原因),然后将第二个字节分配给下一个整个
uint16\u t
(损坏堆栈)

对于您正在尝试的内容,请改用
std::memcpy()
,例如:

std::memcpy(&data_returned, data_str.c_str(), sizeof(data_returned));
否则,如果确实要使用
std::copy()
,则需要确保它知道要将单个字节复制到目标,而不是整个
uint16\t
s,例如:

std::copy(data_str.begin()、data_str.end()、reinterpret_cast(&data_returned));

由于输入和输出都是琐碎的类型,因此应该将其优化为适当的
std::memcpy()
-等效副本。

为了以这种方式使用
std::copy()
,您需要将返回的
数据转换为
字符*
,或者
std::copy()
会将其视为一个
uint16\u t*
并填充两个
uint16\u t
s,而不是您想要的两个
char
s。这会使您的程序具有,这就是为什么您会在
数据中看到一个更改的值。该程序也可能崩溃或做了完全不同的事情

std::copy(data_str.begin()、data_str.end()、reinterpret_cast(&data_returned));

下面是用两个额外选项(
-ggdb-fsanize=address
)编译的程序,以使将来更容易发现类似问题:

为了以这种方式使用
std::copy()
,您需要将
返回的
数据转换为
字符*
,或者
std::copy())
会将其视为一个
uint16\u t*
并填充两个
uint16\u t
s,而不是您想要的两个
char
s。这会使您的程序具有,这就是为什么您会在
数据中看到一个更改的值。该程序也可能崩溃或做了完全不同的事情

std::copy(data_str.begin()、data_str.end()、reinterpret_cast(&data_returned));
以下是使用两个额外选项(
-ggdb-fsanize=address
)编译的程序,以便于将来发现类似问题: