Fla*_*ash 13 c memory-management
在面试的书面回合中提出了这个问题:
#include<alloc.h>
#define MAXROW 3
#define MAXCOL 4
main()
{
int (*p)[MAXCOL];
p = (int (*)[MAXCOL]) malloc(MAXROW*(sizeof(*p)));
}
Run Code Online (Sandbox Code Playgroud)
进程中分配了多少字节?
说实话,我没有回答这个问题.我不明白的任务p.
任何人都可以解释一下答案是什么以及如何推断出来?
它取决于平台.
int (*p)[MAXCOL];声明一个指向MAXCOL元素宽整数数组的指针(在这种情况下MAXCOL当然是4).因此,该指针的一个元素4*sizeof(int)位于目标平台上.
该malloc语句分配的内存缓冲区MAXROW乘以P中包含的类型的大小.因此,总共分配MAXROW*MAXCOL整数.实际字节数取决于目标平台.
此外,可能还有C运行时使用的额外内存(作为malloc中的内部bookeeping,以及之前发生的各种进程初始化位main),这也完全取决于平台.
p是一个指向MAXCOL类型元素数组的指针int,因此sizeof *p(圆括号是多余的)是这样一个数组的大小,即MAXCOL*sizeof(int).
返回价值的演员malloc是不必要的,丑陋的,并被认为是有害的.在这种情况下,它隐藏了一个严重的错误:由于缺少原型,malloc假定隐式返回int,这与其正确的返回类型(void *)不兼容,从而导致未定义的行为.
#include<alloc.h>
#define MAXROW 3
#define MAXCOL 4
main() {
int (*p)[MAXCOL];
p = (int (*)[MAXCOL]) malloc(MAXROW*(sizeof(*p));
}
Run Code Online (Sandbox Code Playgroud)
进程中分配了多少字节?
p是一个指针,所以会占用sizeof(int(*)[MAXCOL])堆栈,这可能看起来令人生畏,但它几乎总是相同sizeof(void*),sizeof(int*)或任何其他指针.显然,指针大小使应用程序的分类为16,32,64等.位,此指针将相应地调整大小.
然后p指向从malloc... 获得的一些记忆
malloc( MAXROW * sizeof(*p) )
Run Code Online (Sandbox Code Playgroud)
sizeof(*p)是指向的int数组的大小p,即sizeof(int) * MAXCOL我们得到的
malloc( MAXROW * (sizeof(int) * MAXCOL) )
Run Code Online (Sandbox Code Playgroud)
从堆请求.为了便于说明,如果我们假设共同的32位int大小,我们将查看48个字节.实际使用情况可以向上舍入到堆例程的任何感觉(堆例程经常使用固定大小的"桶"来加速其操作).
要确认此期望,只需将日志记录功能替换为malloc():
#include <stdio.h>
#define MAXROW 3
#define MAXCOL 4
void* our_malloc(size_t n)
{
printf("malloc(%ld)\n", n);
return 0;
}
int main()
{
int (*p)[MAXCOL];
p = (int (*)[MAXCOL]) our_malloc(MAXROW*(sizeof(*p)));
}
Run Code Online (Sandbox Code Playgroud)
我的Linux机箱输出:
malloc(48)
Run Code Online (Sandbox Code Playgroud)
malloc的返回指针转换为p的类型的事实不会影响完成的内存分配量.
正如R强烈观察到的那样,缺少malloc原型会导致编译器期望malloc返回int而不是实际返回void*.实际上,指针中最小的sizeof(int)字节很可能在转换后仍然存在,如果sizeof(void*)恰好等于sizeof(int),或者 - 更脆弱 - 堆内存恰好开始int尽管指针的大小较大(即所有截断的位都是0),但在一个地址中可表示的地址,然后稍后解除指针的引用可能会起作用.廉价插件:除非看到原型,否则C++不会编译.
也就是说,也许你的alloc.h包含一个malloc原型......我没有alloc.h所以我猜它是非标准的.
任何程序也会为许多其他事物分配内存,例如提供一些可以调用main()的上下文的堆栈帧.内存量因编译器,版本,编译器标志,操作系统等而异.
| 归档时间: |
|
| 查看次数: |
1212 次 |
| 最近记录: |