c++ 中新分配的 int 的内存大小,有没有更好的不同方式来查看它?

Memory size of the new allocated int in c++, Is there a different and better way to see it?

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

#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;
}

不行,没办法。编译器在内部添加有关分配了多少内存以及 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';
    }
}

你几乎不应该使用 new[]。使用 std::vector.


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

也没有办法避免 sizeof,因为 int 的大小可能因实现而异。但这也不是问题,因为 std::vector 不会丢失其类型信息,因此您始终知道一个元素有多大。

如果是 std::vector<char>std::vector<unsigned char>std::vector<signed char>,则不需要乘法,因为这三种字符类型的 sizeof 保证是 1.

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

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];}
};

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

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];

当然,当大小增长大于容量时,内存将需要重新分配,并且需要更多的东西才能使这个包装器真正发挥作用(例如,能够复制会很好)。

底线是:不要做任何这样的事情!要编写一个好的成熟的容器class需要的东西比我在这里概述的要多得多,而且大多数其中的样板并没有真正为您的代码库增加价值,因为 std::vector 已经是一个围绕动态分配内存的薄包装器,它为您提供所需的一切,同时不会为您不使用的东西强加开销。