情况如下:
#include <malloc.h>
int size = 7;
double *a = new double[size];
cout << malloc_usable_size(a) / sizeof(*a) << endl;
//输出结果为 7
int size = 8;
double *a = new double[size];
cout << malloc_usable_size(a) / sizeof(*a) << endl;
//输出结果为 9
//sizeof(a)=sizeof(*a)=sizeof(double)=8
当 size=8 或 1024 其他偶数时,malloc_usable_size 会多一个 size
也就是数组长度为偶数情况下输出结果会比实际的加 1
我想问下这个要怎么处理才始终正确?
或者有没有其他更好的获取指针数组长度的方法?
非常感谢!
1
codehz 2020-01-05 18:16:39 +08:00 via Android 2
答案是不能获得长度(
你必须用个变量去记录 |
2
inhzus 2020-01-05 18:43:27 +08:00 via Android 1
malloc_usable_size() returns the number of bytes available in the dynamically allocated buffer ptr, which may be greater than the requested size (but is guaranteed to be at least as large, if the request was successful). Typically, you should store the requested allocation size rather than use this function.
这个函数的文档有提到这点的。建议使用一个函数最好看看官方文档的~ 回到获取指针指向数组的长度这个问题,是不能直接得到的(有什么奇技淫巧就不晓得了)。建议用 std::array 或 std::vector |
4
crclz 2020-01-05 20:36:00 +08:00 1
c 语言是设计的很简练的语言,它是个人设计的,并非组织设计的。c 语言很多地方按照约定来设计的,可能在主力语言是 java 或者 c#的人看来比较不美,但是实际上这是简洁的美。
例如:字符串以'\0'结尾。与字符串操作相关的库函数也都是基于这个假设。 再例如,库函数、变量命名都有大量缩写,例如 getchar, fopen,而不是 OpenFile()这种风格。 而数组的约定,就是将数组与指针等同起来理解。如果需要记录长度,请单独拿一个变量。 |
7
leido 2020-01-05 20:49:30 +08:00 via Android
哪本书告诉你堆内存可以这样算空间??
栈上才可以,前提是在申请栈空间的函数内 |
8
laminux29 2020-01-05 22:13:40 +08:00
老哥是 Java 用多了吧...就算 malloc_usable_size 这函数能给出正确的结果,万一编译器把它当函数来编译,那么它的性能也有可能比自己用变量记录慢得多啊。
|
10
ipwx 2020-01-05 22:24:28 +08:00
谁说你申请多少内存,malloc 就一定划多少内存给你的?为了解决内存碎片,malloc 很可能以一定程度地牺牲内存为代价,给你划一块稍微大一点但是不至于引起内存碎片的内存给你。
一个经典的内存分配算法是 https://en.wikipedia.org/wiki/Buddy_memory_allocation |
11
FrankHB 2020-01-06 03:56:41 +08:00
@hobochen C2x 都快出来了还 2011,,,
……嘛,N1570 以后的 draft 和正式出版的太接近的得要密码( |
12
FrankHB 2020-01-06 03:58:41 +08:00
……哦这个是 C 艹么。
送 LZ 一句话: “恁也配用 new ?” 理解好了再倒腾,对谁都好,谢谢合作。 |
13
lomewcl 2020-01-06 06:17:44 +08:00 1
不是很清楚 malloc 族相关的函数能不能用到 new 上,懒得查了。
堆分配的内存以 chunk 为最小单位,涉及对齐等,比申请的空间大一点是很正常的。 |
14
geelaw 2020-01-06 06:53:40 +08:00 via iPhone
@FrankHB #12 楼主这个 malloc_usable_size 都不是 C 或者 C++ 的一部分(
|
15
augustheart 2020-01-06 09:34:32 +08:00 1
不要去计算堆内存,虽然其实有些方法可以,但是不可靠,不能得到精确的内存。因为 c 分配内存的时候就不会严格按照申请的长度分配,会有等于指针长度的对齐。
另外,c 的数组后面是有 0 占位的,配合上对齐的效果,所以会出现 size + 1 的情况(不能理解的话就过吧,不搞逆向的话不需要理解这种细节,因为不能靠这个写代码,会出人命的) |
16
FrankHB 2020-01-06 20:44:42 +08:00
@lomewcl 不用查了,都没给 main,甚至都没说是完整的翻译单元,那至少能用重定义::operator new 的方式可移植地保证始终不正确。
|
17
FrankHB 2020-01-06 20:45:10 +08:00
::operator new→::operator new[]。
|