【发布时间】:2023-03-30 15:20:01
【问题描述】:
对于向量,可以假设元素连续存储在内存中,允许将范围 [&vec[0], &vec[vec.capacity()) 用作普通数组。例如,
vector<char> buf;
buf.reserve(N);
int M = read(fd, &buf[0], N);
但现在向量不知道它包含 M 个字节的数据,由 read() 外部添加。我知道 vector::resize() 设置了大小,但是它也清除了数据,所以在 read() 之后不能用来更新大小打电话。
有没有一种简单的方法可以将数据直接读入向量并在之后更新大小?是的,我知道一些明显的解决方法,比如使用一个小数组作为临时读取缓冲区,并使用 vector::insert() 将其附加到向量的末尾:
char tmp[N];
int M = read(fd, tmp, N);
buf.insert(buf.end(), tmp, tmp + M)
这行得通(这就是我今天正在做的事情),但让我感到困扰的是,如果我可以将数据直接放入向量。
那么,在外部添加数据时,有没有一种简单的方法可以修改矢量大小?
【问题讨论】:
-
您确定
&buf[0]在调试模式下工作吗?例如,在 Visual Studio 上,在调试模式下std::vector::operator[]执行范围检查。因此,如果buf为空,则该表达式将抛出。 -
我使用 GCC,并通过 valgrind 运行程序以确保没有发生内存错误。我只能说,使用 GNU libstdc++ 实现,这是可行的。 &vec[0] 似乎给你一个指向保留内存的直接指针,不管 size()。
-
@user984228:如果您乐于依赖 GCC 的实现细节(这是一个 BAD IDEA (TM)),那么您可以查看其实现
vector的源代码。你可以看到它存储begin和end指针和容量的位置,如果你只是覆盖end指针,我很确定这会改变你想要的大小。只要在容量足够大的情况下复制resize()的实现,就可以忽略memset/fill/whatever。当然,您必须解决一些private修饰符,也许通过在偏移量中进行硬编码。 -
@SteveJessop:我刚刚死了一点。
-
@Matthieu:相当。如果所有这些听起来都是个坏主意,那么希望依靠 GCC 似乎可以让您写入仅保留而不是调整大小的空间这一事实,这听起来也是个坏主意 :-)