在"stack"上分配的向量可以在函数之间传递吗?

Can a vector allocated on the "stack" be passed from function to function?

本文关键字:之间 函数 stack 分配 向量      更新时间:2023-10-16

我知道,当函数完成执行时,在函数堆栈上分配的变量将变得不可访问。然而,向量类型在堆上分配它们的元素,无论它们是如何分配的。例如,

vector<int> A;

将在堆而不是堆栈上为其元素分配空间。

我的问题是,假设我有以下代码:

int main(int argc, char *argv[]) {
    // initialize a vector
    vector<int> A = initVector(100000);
    // do something with the vector...
    return 0;
}

// initialize the vector
vector<int> initVector(int size) {
    vector<int> A (size);  // initialize the vector "on the stack"
    // fill the vector with a sequence of numbers...
    int counter = 0;
    for (vector<int>::iterator i = A.begin(); i != A.end(); i++) {
        (*i) = counter++;
    }
    return A;
}

在主函数中使用向量A时,我会遇到内存访问问题吗?我试了好几次,它们都正常工作,但我担心这可能只是运气。

在我看来,向量A在堆上分配元素,但它在堆栈本身上分配了一些"开销"参数(可能是向量的大小)。因此,如果这些参数被另一个分配覆盖,那么在主函数中使用向量可能会导致内存访问问题。有什么想法吗?

当你执行"return A;"时,你会按值返回,所以你会得到向量的副本——C++会创建一个新实例,并在它上调用copy-constructor或operator=。所以在这种情况下,内存分配在哪里并不重要,因为你无论如何都必须复制它并销毁旧副本(尽管有一些可能的优化)。

向量(以及所有其他STL容器)中的数据也会按值移动,因此您存储整数的副本,而不是指向它们的指针。这意味着您的对象可以在任何容器操作中多次复制,并且它们必须正确实现复制构造函数和/或赋值运算符。默认情况下,C++会为您生成这些(只是对所有成员变量调用copy-ctor),但它们并不总是做正确的事情。

如果要将指针存储在STL容器中,请考虑使用共享指针包装器(std::shared_ptr或boost::shared-ptr)。它们将确保正确处理内存。

是的,它将正常工作,因为元素的内存已分配,这将用于构建vector<int> A =变量。然而,就性能而言,这并不是最好的主意。

我建议通过将您的功能更改为如下

void initVector(vector<int>& a, int size) 

有关用法的其他参考,请参阅从函数返回STL矢量…和[C++]从函数返回矢量。

有关性能的其他参考(使用C++11),请参阅从C++0x 中的函数调用返回std::vector的正确方式(移动语义)

C++向量实际上有两块内存,它们用一个指针链接。第一个在堆栈中,第二个在堆中。因此,在单个对象中同时具有堆栈和堆的特性。

std::vector<int> vec;
vec.push_back(10);
vec.push_back(20);
vec.push_back(30);
std::cout << sizeof(vec) << std::endl;

运行该代码后,您会注意到堆栈区域不包含元素,但它仍然存在。因此,当您将向量从一个函数传递到另一个函数时,您需要操作堆栈区域,并且向量将像任何其他基于堆栈的对象一样被复制。

相关文章: