C++ - 重写/重构整个std::vector的最佳实践

4
如果我有一个std::vector,我想要完全覆盖(不仅仅是调整大小),在内存管理方面,什么是最安全的方法?例如:
int main() {
    std::vector<float> X (5, 5.0);
    X = std::vector<float> (6, 6.0);
    X = std::vector<float> (4, 4.0);
}

将创建一个值为5.0的长度为5的浮点数向量。然后将其用值为6.0的大小为6的向量覆盖,然后用值为4.0的大小为4的向量覆盖。如果我要执行此类操作无限次,是否存在破坏或泄漏内存的风险?在每次覆盖之前应该使用clear()吗?有没有更有效的方法来实现这一点?
我相信这个问题已经被问了很多次,但谷歌并没有提供我所需要的确切情况。
谢谢!

相关阅读:https://dev59.com/4mkv5IYBdhLWcg3wpCIz。是的,你可能会导致泄漏,但由于它们在堆栈上,这可能并不重要。 - CollinD
1
从安全角度来看,向量不会泄漏内存。 - M.M
2个回答

5

std::vector有特定的成员函数来实现这一点。除了分配器和复制/移动,每个vector构造函数都有一个相应的assign重载,可以完成同样的事情。所以如果你想要重用vector的存储空间,只需使用它:

std::vector<float> X (5, 5.0);
X.assign(6, 6.0);
X.assign(4, 4.0);

当然,不能保证vector实现不会重新分配内存。但是,这将是一个非常愚蠢的实现。

2

这种方法会有内存损坏或泄漏的风险吗?

没有。

每次覆盖前我是否应该使用 clear()

不必要。

有更有效的方法来实现这个吗?

这高度取决于您替换向量的模式。在您当前的代码中,每次都会分配一个新的向量,然后释放旧向量并将新向量移动到 X 中。

分配和释放是昂贵的操作。可能更好的想法是只循环遍历向量并更改每个已经存在的元素和/或将新元素推入现有向量。以下是示例:

std::vector<float> X (5, 5.0);

std::transform(begin(X), end(X), begin(X), [](int){ return 6.0; }); 
X.resize(6, 6.0);

std::transform(begin(X), end(X), begin(X), [](int){ return 4.0; }); 
X.resize(4);

如果元素数量很多且对象不是简单的整数,那么这可能导致代码运行变慢。

最好的方法是编写两个版本并对它们进行基准测试。


谢谢提供的信息。将来我会尽量避免不必要的内存分配和释放。 - Ross Allen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接