2013-05-08 49 views
2

下面是一个简单的程序简单性病插入 - 擦除 - 插入::双端队列<char>给人奇怪的结果

#include <iostream> 
#include <deque> 
#include <string.h> 

std :: deque <char> d; 

int main() 
{ 
    const char * X = "abcdefg"; 

    d .insert (d .end(), X, X + strlen (X)); 

    d .erase (d .begin(), d .begin() + 4); 

    d .insert (d .end(), X, X + strlen (X)); 

    std :: cout .write (& d [0], d .size()); 
} 

我预期的输出是“efgabcdefg”,实际输出,以十六进制,是

65 66 67 00 00 00 00 C9 0B 02 

这是“efg ???????”

出了什么问题?

+3

什么是所有的空间? – TemplateRex 2013-05-08 13:49:43

+0

我慷慨地使用空格。我使用连续的非空行仅用于较长的参数列表,或者当短语句形成一个逻辑块时(例如,'start + = used; \ nsize - = used;' – spraff 2013-05-08 13:57:00

+0

不要为小东西出汗,但几乎99.9%程序员在地址/解引用运算符'.',' - >','::','*','&'和'[]'周围不使用空格。你允许在工作中使用它吗?(至少它不像在任何地方没有空格那么糟糕,就像在混淆的C代码竞赛中一样) – TemplateRex 2013-05-08 14:01:02

回答

2

您输出的问题是deque不能保证其元素连续存储,事实上几乎肯定不会。这意味着当您获取第一个元素的地址和大小时,您可能无法访问deque的所有元素。

您有多种方法可以解决您的问题。

最简单的似乎是使用string而不是deque。然后,打印变得微不足道,而且随后的附加裁剪也变得微不足道。

您也可以使用例如ostream_iterator打印出deque的内容。

最后,您可以使用vector而不是保证连续存储其元素。

6

std::deque不会将其元素连续存储在内存中。如果您需要,请使用std::vector。换句话说,&d[0]不是长度为d.size()的缓冲区的开始,您可以将其传递到write()

+2

非常简洁。 +1。作为'write()'的一个变种,['std :: ostream_iterator'](http://www.cplusplus.com/reference/iterator/ostream_iterator/)可以删除那个“连续”的需求。 – 2013-05-08 13:52:43

2

正如其他人所指出的,你不能在 的结果&deque<>::operator[]上做指针运算,并且期望任何合理的 。这是保证为std::vector,但这是一个特殊情况的 。

做你仿佛想要的惯用方法是:

std::copy(d.begin(), d.end(), std::ostream_iterator<char>(std::cout)); 

这将是真实的,不管d类型。

但为什么不使用std::vector<char>。对于便宜的复制 类似char,无论如何它可能比deque快,即使对于 erase开头。