了解我有多少内存可用于动态向量 C++ [关闭]

Posted

技术标签:

【中文标题】了解我有多少内存可用于动态向量 C++ [关闭]【英文标题】:Understand how much memory i have avaible for a dynamical vector c++ [closed] 【发布时间】:2015-12-19 14:26:26 【问题描述】:

我是 C++ 编程新手;在我的程序中,从 .csv 文件中读取后,我必须动态分配一个向量向量和两个带有 std::vector 的向量。如果无法在堆中分配矩阵我必须使用不同的功能。但我不知道从分配的角度来看这是如何表现的。

【问题讨论】:

对不起,我搜索了很多,但是关于这个问题我什么也没找到。因为我不知道 std::vector 中的向量单元是如何存储的以及它占用了多少内存 @Federico 向量将占用与相同大小的数组相同数量的动态内存。 与相同对象的动态 C 数组相比,向量将使用固定的微量内存。在大向量中可以忽略这个微不足道的额外内容。如果你有大量的小向量,那么这些微不足道的额外可能值得担心。此外,如果您事先知道最终大小and done a reserve,则增量构建的向量(例如使用push_back)占用的空间比它本来的要多。 我对分配发生的情况进行了详尽的解释。为了进行更深入的讨论,我建议您阅读 Bjarne Stroustrup 在“抽象机制”部分中的“C++ 编程语言第 4 版”文本 堆内存可以增长和缩小。有时,内存是从操作系统内核中获取并随后释放的。另见this 【参考方案1】:

std::vector 是 C++ 标准库提供的“用户定义类型”。它用作动态保存其数据的容器。这就是它可以与push_back() 一起成长的原因。

让我们检查一个非常简化的 std::vector 版本: 从此类实例化的对象将仅包含整数作为数据,并且必须在创建时指定大小

class VectorOfInts 

private:
    int* data; // pointer to where all of the data is stored on heap
    int sz;

public:
    VectorOfInts(int size) :datanew int[size], szsize  
    
        for (int i=0; i<sz; ++i) data[i]=0; //initialize all ints to 0 
    

    ˜VectorOfInts()  delete[] data;  //when the VectorOfInts is destroyed, 
    //we have to remember to release all of our data.

    int getSize() const
    
        return sz;
    

    void setValue(int index, const int& value)
    
        if(index>=sz || index<0) 
            
                std::cout<<"invalid index\n";
                return;
            
        //since value is type int which is an integral type, it is copied
        //if we had a vector of struct or class instead, 
        //copy constructor (or suitable move constructor if defined)
        //would have been called. 
        //this is the most crucial part to understand about this code.
        data[index] = value;  
    
;

如您所见,数据由免费存储中的VectorOfInts 在内部动态管理。事实上,无论您通过构造函数创建多大的容器,类对象本身的大小都是相同的。这是因为您的VectorOfInts 本身只有一个指针和一个int

每次设置值时,都必须将参数复制到由VectorOfInts 分配的动态内存中。对于int,这没什么大不了的,但是如果我们有一个大对象向量(具有自己的指针和对象作为字段)而不是int,建议定义一个合适的移动构造函数或考虑保留一个指针向量而不是实际对象。

这是std::vector 工作原理的精髓。有一些不同之处,包括以下内容:

1- std::vector 可以随大小而增长和缩小:std::vector 将跟踪“容量”,即在向量增长时分配和可用的空闲存储的总大小,以及“大小”是向量所包含的实际元素数。如果大小超过容量,向量将在堆中重新分配更大的内存块,复制所有旧数据,并释放旧内存位置。

2- std::vector 允许泛型类型内容:这对实现来说不是问题,因为向量将为对象类型的大小 * 元素的数量分配内存。这保证有效,因为每个向量在其生命周期内只包含特定类型的对象。

我现在将提供几个示例来说明处理std::vector 时内存的确切位置:

#include <iostream>
#include <vector>

void  helper()

    std::vector<int> A; //vector created on the stack
    int a=5;
    int b=6;
    A.push_back(a); //a is copied to another place in memory allocated by A
    A.push_back(b); //same thing with b, they are both copied; 

    std::vector<int>* B = new std::vector<int>(); //B is a pointer only
    //B occupies as much space as any pointer on your machine, but what it points to
    //is a dynamically allocated block of memory that holds a vector
    B->push_back(a); //a is copied to free store
    B->push_back(b); //same thing with b;

    free(B); //this is extremely important, 
             //since B is allocated on the heap, it must be freed
             //or else we will have a memory leak.  
             //the destructor for std::vector is smart
             //it will in turn free its own dynamically allocated memory upon destruction.

 //when this function returns, a, b and A are all destroyed
  // because they fall off the stack
  //A's destructor is called implicitly and the block of memory
  // that is allocated by A is free's by its destructor

在我们的主要功能中:

int main() 


    helper(); 

    std::vector<int> A;  //created on the stack; 
    A.push_back(1); //the value 1 is copied to dynamic memory by A
    A.push_back(2);
    A.push_back(3);

    std::vector<int> B;  //created on the stack; 
    B.push_back(4); //the value 4 is copied to dynamic memory by B
    B.push_back(5);
    B.push_back(6);

    std::vector<std::vector<int>> C;  //also created on the stack

    C.push_back(A);  //the content of A (including its internal pointers) 
                     //is copied to an area of heap allocated by C
    C.push_back(B);  //same for B, notice that A and B are copied 



    return 0;
 //destructor for A, B and C are called. 

【讨论】:

以上是关于了解我有多少内存可用于动态向量 C++ [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

C++动态内存

C++ 动态分配的 std::vector

C++ 向量初始容量

c++中字符串向量的索引[关闭]

C++内存管理

C++内存管理