当你可以使用指针时,使用malloc的重点是什么?

时间:2015-07-16 09:42:29

标签: c malloc

您只能使用指针存储尽可能多的数据吗? 为什么必须使用malloc()来获取更多内存?

int * a;
int max, i;
printf("Enter the maximum number you want: ");
scanf("%d", &max);

for (i = 0; i < max; i++)
{
    * (a + i) = i;
}

for (i = 0; i < max; i++)
{
    printf("%d\n", * (a + i));
}
return 0;

所以我让用户选择任何数字,计算机将分配内存&#39;对?而不是使用以下代码:

a = (int *) malloc(10 * sizeof(int));

3 个答案:

答案 0 :(得分:8)

在您的代码中,

  * (a + i) = i;

是错误的,因为你试图写入未初始化的内存。这反过来调用undefined behaviour

详细说明,仅定义指针不会自动为该指针分配无限可访问内存。您需要添加指针指向的位置。当您只是定义一个指针(本地)时,它指向一些未知内存位置,这很可能既不是有效的,也不是您的程序可以访问的。因此,当您尝试访问该内存位置时,它实际上是访问某些无效内存。这是UB。

所以,

  

为什么必须使用malloc来获取更多内存?

malloc()不用于获取更多内存,而是用于访问必需内存位置。

编辑:

关于你的编辑,

 a = (int *) malloc(10 * sizeof(int));

要添加两件事,

  1. malloc() Cmalloc()家人的回复价值see why not to cast
  2. 在使用返回的指针之前,请务必检查Book{ //DB field bookID int PK, bookName nvarchar, artID int FK Article(artID) int OriginalPrice; int Discount; //computed public int SellPrice{ get{ return (OriginalPrice - OriginalPrice*Discount/100 )/500*500; } } } 是否成功。

答案 1 :(得分:2)

指针必须指向内存中的某个位置,所以永远不要写

int* x;
*x=...;

但写下

int* x=expression that results in an valid address;

首先考虑一台没有MMU的简单计算机和一个花哨的多任务操作系统。然后您可以使用任何地址,但您必须知道您不会替换您的代码和任何重要数据。您将受益于为代码,调用堆栈和其他数据提供保留空间。有些机器将地址连接到外围设备,因此在那里写一些物理内容会发生。这称为内存映射I / O.要知道你在做什么,你可以创建你的地址布局,这在16位机器上可能看起来像

+------------------+ 0x0000
| Memory mapped IO |
+------------------+ 0x0100
| Program          |
|                  |
+------------------+ 0x4000
| Call stack       |
| (local variables)|
+------------------+ 0x8000
| Other data       |
| globals          |
| heap             |
+------------------+ 0xffff

这个虚构机器有255个I / O端口(保留0x0000),并将在地址0x0100上启动程序。地址布局的其余部分由您决定。这里为程序保留了16128个字节,堆栈为16384个字节,其他数据为32767个字节。如果您知道您的程序永远不会超过8 kB,那么随意增加您的调用堆栈或堆。设置电机转速的程序可能看起来像

int main()
    {
    const uint8_t* speed_regulator=(const uint8_t*)0x0001; //Port for speed controller is 0x0000
    uint8_t* motor_voltage=(uint8_t*)0x0002; //Port for motor controller

    while(true)
        {
        *motor_voltage=*speed_regulator;
        }
    }

这里必须小心,因此编译器不会优化循环,这是我们的数据泵。

现在您需要一个具有虚拟内存和所有现代功能的多任务系统。但是你不能再使用任意地址了。为了能够为您提供有效的地址,并告知操作系统您需要多少内存,函数malloc已存在。

答案 2 :(得分:1)

  

所以我让用户选择任何数字,计算机将'分配内存'对吗?

有些语言就是这样的;运行时环境将根据需要从堆(或任何内存池)中分配内存。

C不起作用。当你宣布

int *a;

a最初并未指出任何有意义的内容;如果声明static或在文件范围,它最初包含NULL,并且如果在块中声明它包含不确定值,该值可能指向可写内存位置,也可能不指向可写内存位置。它不会自动指向堆,并且写*(a + i) = i(或a[i] = i,这是相同的事情)将不会自动分配任何新内存。

C给程序员带来了管理动态分配内存的所有负担。如果在运行时需要额外的内存,则必须使用mallocrealloc,当您完成该内存后,必须使用free取消分配。