代码之家  ›  专栏  ›  技术社区  ›  Allamo Olsson

c++中新分配的int的内存大小,是否有其他更好的方法来查看它?

  •  2
  • Allamo Olsson  · 技术社区  · 6 年前

    在这个程序中,我试图找出为指针分配了多少内存。我可以这样看,它应该是1 gibibyte,即=1 073 741 824字节。我的问题是,我能通过的唯一方法是取int的大小4,然后乘以常数。有不同的方法吗?

    #include "stdafx.h"
    #include <iostream>
    #include <new>
    
    int main(){
    
        const int gib = 268435256; //Created a constant int so I could allocate 1 
                               //Gib memory
        int *ptr = new int [gib];
    
        std::cout << sizeof (int)*gib << std::endl;
        std::cout << *ptr << std::endl;
        std::cout << ptr << std::endl;
    
        try {
        }catch (std::bad_alloc e) {
            std::cerr << e.what() << std::endl;
        }
    
        system("PAUSE");
        delete[] ptr;
    
        return 0;
    }
    
    2 回复  |  直到 4 年前
        1
  •  6
  •   Christian Hackl    6 年前

    不,不可能。编译器在内部添加有关分配了多少内存以及创建了多少元素的信息 new[] ,否则无法执行 delete[] 正确地然而,在C++中没有可移植的方法来获取这些信息并直接使用它们。

    因此,您必须在仍然知道的情况下单独存储大小。

    事实上,你没有,因为 std::vector 是否为您:

    #include <iostream>
    #include <vector>
    #include <new>
    
    int main() {
    
        const int gib = 268435256;
    
        try {
            std::vector<int> v(gib);
            std::cout << (v.capacity() * sizeof(int)) << '\n';
        } catch (std::bad_alloc const& e) {
            std::cerr << e.what() << '\n';
        }
    }
    

    你不应该使用 新建[] 使用 标准::矢量


    请注意,我使用了 capacity 而不是 size 因为 大小 告诉您向量表示的项目数,该数字可以小于向量当前分配内存支持的元素数。

    也无法避免 sizeof ,因为 int 可能因实施而异。但这也不是问题,因为 标准::矢量 不能丢失其类型信息,因此您总是知道一个元素有多大。

    如果它是一个 std::vector<char> A. std::vector<unsigned char> 或a std::vector<signed char> ,因为这三种字符类型' sizeof公司 保证为1。

        2
  •  1
  •   463035818_is_not_an_ai    6 年前

    无法从指针检索分配的内存量。让我们暂时忘记存在标准容器(和智能指针),然后可以使用封装指针和大小的结构。我能想象的最简单的动态数组是:

    template <typename T>
    struct my_dynamic_array {
            size_t capacity;
            T* data;
            my_dynamic_array(size_t capacity) : capacity(capacity),data(new T[capacity]) {}
            ~my_dynamic_array() { delete[] data; }
            const T& operator[](int i) const { return data[i];}
            T& operator[](int i) { return data[i];}
    };
    

    请注意,his只是为了演示而提供的一个基本示例,例如,您不应该复制此结构的实例,否则会发生不好的事情。但是,它可以这样使用:

    my_dynamic_array<int> x(5);
    x[3] = 1;
    std::cout << x[3];
    

    即在使用数组的代码中没有指针,也没有手动分配内存,这是一件好事。实际上,这本身已经是一件大事了,因为现在您可以使用RAII并且不能忘记删除内存。

    接下来,您可能需要调整阵列的大小,这只需要多一点样板文件(再次强调:不要小题大做!):

    template <typename T>
    struct my_dynamically_sized_array : my_dynamic_array<T> {
            size_t size;
            my_dynamically_sized_array(size_t size, size_t capacity) : 
                my_dynamic_array<T>(capacity),size(size) {}
            void push(const T& t) {
                my_dynamic_array<T>::data[size] = t;
                ++size;
            }
    };
    

    它可以这样使用:

    my_dynamically_sized_array<int> y(0,3);
    y.push(3);
    std::cout << y[0];
    

    当然,当大小超过容量时,需要重新分配内存,并且需要更多的东西才能使这个包装真正起作用(例如,能够复制就好了)。

    底线是: 不要这样做! 要编写一个好的完整的容器类,需要比我在这里概述的内容多得多,其中大部分内容都是锅炉板,不能真正为您的代码库增加价值,因为 std::vector 已经有了一个围绕动态分配内存的薄型包装器,它可以提供您所需的所有内容,同时不会对您不使用的内容施加开销。