内存分配问题

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.

任何人都可以解释一下答案是什么以及如何推断出来?

Bil*_*eal 8

它取决于平台.

int (*p)[MAXCOL];声明一个指向MAXCOL元素宽整数数组的指针(在这种情况下MAXCOL当然是4).因此,该指针的一个元素4*sizeof(int)位于目标平台上.

malloc语句分配的内存缓冲区MAXROW乘以P中包含的类型的大小.因此,总共分配MAXROW*MAXCOL整数.实际字节数取决于目标平台.

此外,可能还有C运行时使用的额外内存(作为malloc中的内部bookeeping,以及之前发生的各种进程初始化位main),这也完全取决于平台.


R..*_*R.. 7

p是一个指向MAXCOL类型元素数组的指针int,因此sizeof *p(圆括号是多余的)是这样一个数组的大小,即MAXCOL*sizeof(int).

返回价值的演员malloc是不必要的,丑陋的,并被认为是有害的.在这种情况下,它隐藏了一个严重的错误:由于缺少原型,malloc假定隐式返回int,这与其正确的返回类型(void *)不兼容,从而导致未定义的行为.

  • @Chris:使用超过预期的实现不会使R的计算无效.你只能计算程序要求`malloc`分配多少 - 一个下限 - "malloc"可以完全自由地以它想要的任何方式舍入它,基于它在内部使用的任何固定大小的桶或页面大小来加速它的速度算法.此外,程序可以从其他初始化代码中分配堆 - 在比较期望re`p`和明确请求的`malloc`时,请注意不要包含堆. (2认同)

Nav*_*een 6

sizeof(*p)会的MAXCOL*sizeof(int).所以总共MAXROW*MAXCOL*sizeof(int)分配了多少字节.


Dav*_*har 6

您可能需要查看cdecl以获取将C声明翻译成英语的帮助.在这种情况下,int (*p)[4];成为declare p as pointer to array 4 of int.


Ton*_*roy 5

#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()的上下文的堆栈帧.内存量因编译器,版本,编译器标志,操作系统等而异.