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
已经是一个围绕动态分配内存的薄包装器,它为您提供所需的一切,同时不会为您不使用的东西强加开销。
在这个程序中,我试图找出为我的指针分配了多少内存。我可以通过这种方式看到它应该是 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
已经是一个围绕动态分配内存的薄包装器,它为您提供所需的一切,同时不会为您不使用的东西强加开销。