简体   繁体   English

std :: copy行为和指针算法

[英]std::copy behavior and pointer arithmetic

I'm writing something to serialize data hence I need to be able to write to specific memory locations for another process to be able to deserialize the result. 我正在写一些东西来序列化数据,因此我需要能够写到特定的内存位置,以便另一个进程能够反序列化结果。

Let's say I have two words to serialize into two blocks of 10 bytes each it should look like this. 假设我有两个单词要序列化为两个10字节的块,每个块应该看起来像这样。

|---------------------|---------------------|
|         10          |          10         | 
|---------------------|---------------------|
|        word1        |         word2       |
|---------------------|---------------------|

Here's an example of what I wrote. 这是我写的一个例子。

#include <algorithm>
#include <string>
#include <iostream>

int main()
{
    const char *str1 = "abcd";
    const char *str2 = "efgh";
    char *buffer = new char[20];
    char *cursor = buffer;
    cursor = std::copy(str1, str1 + 10, cursor);
    cursor = std::copy(str2, str2 + 10, cursor);
    std::cout << std::string(buffer, buffer + 8) << std::endl;    
}

However we can see in the result that the two words end up next to each other. 但是,我们可以看到结果是两个单词彼此相邻。 Obviously I need to do some padding but why is it so ? 显然我需要做一些填充,但是为什么会这样呢? My guess was std::copy would copy "abcd" and then continue to copy 6 more chars even though it's whatever trash is sitting in memory at that time. 我的猜测是std :: copy会复制“ abcd”,然后继续复制6个以上的字符,即使当时内存中有什么垃圾。

There are multiple bugs in the shown code. 显示的代码中存在多个错误。

cursor = std::copy(str1, str1 + 10, cursor);
cursor = std::copy(str2, str2 + 10, cursor);

Both str1 and str2 point to string literals that consist of 4 characters plus a trailing '\\0' byte, each. str1str2str1由4个字符加上尾随的'\\0'字节组成的字符串文字。 That's what string literals are. 这就是字符串文字。 Five bytes each. 每个五个字节。 So, in the end, the above code attempts to copy the first ten bytes out of five valid bytes. 因此,最后,以上代码尝试从五个有效字节中复制前十个字节。 Twice. 两次。 This is undefined behavior, twice over. 这是未定义的行为,超过两次。

std::cout << std::string(buffer, buffer + 8) << std::endl;

This will construct a std::string , initializing it to the first 8 bytes of a 20 byte buffer; 这将构造一个std::string ,将其初始化为20字节缓冲区的前8个字节; then write its contents to std::cout . 然后将其内容写入std::cout This is already undefined behavior, at this point. 在这一点上,这已经是未定义的行为。 Whatever output you get, from this, is completely meaningless, and could be anything. 由此获得的任何输出都是完全没有意义的,并且可以是任何东西。 Or, your program could crash before it even gets to this point. 否则,您的程序甚至可能在此之前崩溃。 That's what "undefined behavior" means. 这就是“未定义的行为”的意思。

why is it so ? 为什么会这样呢?

Because you increment the iterator (pointer) beyond the bounds of the array, and the behaviour of the program is undefined. 因为您将迭代器(指针)增加到数组的边界之外,所以程序的行为是不确定的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM