这个问题的灵感来自一个类似的问题:delete []"如何"知道操作数数组的大小?
我的问题有点不同: 有没有办法以编程方式确定C++数组的大小?如果没有,为什么? 我看到的每个接受数组的函数也需要一个整数参数来赋予它大小.但正如链接问题指出的那样,delete[]
必须知道要释放的内存大小.
考虑这个C++代码:
int* arr = new int[256]; printf("Size of arr: %d\n", sizeof(arr));
这打印" Size of arr: 4
",这只是指针的大小.有一些打印256的函数会很好,但我不认为C++中存在一个函数.(同样,问题的一部分是为什么它不存在.)
澄清:我知道如果我在堆栈上声明数组而不是堆(即" int arr[256];
"),则sizeof
运算符将返回1024(数组长度*sizeof(int)).
delete []
确实知道分配的大小.但是,该知识驻留在运行时或操作系统的内存管理器中,这意味着编译期间编译器无法使用它.并且sizeof()
它不是一个真正的函数,它实际上被编译器评估为常量,这是动态分配的数组无法做到的,它的大小在编译期间是未知的.
另外,请考虑以下示例:
int *arr = new int[256]; int *p = &arr[100]; printf("Size: %d\n", sizeof(p));
编译器如何知道它的大小p
是多少?问题的根源是C和C++中的数组不是第一类对象.它们衰减为指针,并且编译器或程序本身无法知道指针是指向由new
一个对象分配的内存块的开头,还是指向一个块中间的某个位置.分配的内存new
.
其中一个原因是C和C++将内存管理留给程序员和操作系统,这也是他们没有垃圾收集的原因.实现new
并且delete
不是C++标准的一部分,因为C++旨在用于各种平台,这些平台可以以非常不同的方式管理它们的内存.如果您为最新的Intel CPU上运行的Windows框编写文字处理器,可以让C++跟踪所有已分配的数组及其大小,但是当您编写运行的嵌入式系统时,这可能是完全不可行的.一个DSP.
不,在标准C++中没有办法做到这一点.
没有什么理由不是我所知道的.可能,大小被认为是一个实现细节,最好不要暴露.请注意,当您说malloc(1000)时,无法保证返回的块是1000字节 - 只有它至少为 1000字节.最有可能的是大约1020(1K减去4个字节的开销).在这种情况下,"1020"大小是运行时库记住的重要大小.当然,这会在实现之间发生变化.
这就是为什么标准委员会添加了std:vector <>,它确实跟踪它的确切大小.
那么实际上有一种方法可以确定大小,但它不是"安全的",并且与编译器和编译器不同...... 因此它根本不应该被使用.
当你这样做:int*arr = new int [256];
256是无关紧要的,你会得到256*sizeof(int)假设这个情况1024,这个值可能存储在(arr - 4)
那么给你一些"项目"
int*p_iToSize = arr - 4;
printf("项目数%d",*p_iToSize/sizeof(int));
对于每个malloc,new,无论你收到的连续内存块之前的什么,都会分配一个空间,其中包含有关你给出的内存块的一些信息.
处理此问题的常用方法是使用向量
int main() { std::vectorv(256); printf("size of v is %i capacity is %i\n", sizeof(int) * v.size(), sizeof(int) * v.capacity()); }
或预定义大小
const int arrSize = 256; int main() { int array[arrSize]; printf("Size of array is %i", sizeof(int) * arrSize); }