C语言中的malloc使用详解

 更新时间:2015年08月12日 10:45:23   作者:zinss26914  
这篇文章主要介绍了C语言中的malloc的使用,包括用其动态申请二维数组等功能,需要的朋友可以参考下

一、原型:extern void *malloc(unsigned int num_bytes);

头文件:#include <malloc.h> 或 #include <alloc.h> (注意:alloc.h 与 malloc.h 的内容是完全一致的。)

功能:分配长度为num_bytes字节的内存块

说明:如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。

当内存不再使用时,应使用free()函数将内存块释放。

举例:

#include<stdio.h>
#include<malloc.h>
int main()
{
  char *p;
 
  p=(char *)malloc(100);
  if(p)
    printf("Memory Allocated at: %x/n",p);
  else
    printf("Not Enough Memory!/n");
  free(p);
  return 0;
}


二、函数声明(函数原型):

  void *malloc(int size);

  说明:malloc 向系统申请分配指定size个字节的内存空间。返回类型是 void* 类型。void* 表示未确定类型的指针。C,C++规定,void* 类型可以强制转换为任何其它类型的指针。这个在MSDN上可以找到相关的解释,具体内容如下:   

malloc returns a void pointer to the allocated space, or NULL if there is insufficient memory available. To return a pointer to a type other than void, use a type cast on the return value. The storage space pointed to by the return value is guaranteed to be suitably aligned for storage of any type of object. If size is 0, malloc allocates a zero-length item in the heap and returns a valid pointer to that item. Always check the return from malloc, even if the amount of memory requested is small.

三、malloc与new的不同点

  从函数声明上可以看出。malloc 和 new 至少有两个不同: new 返回指定类型的指针,并且可以自动计算所需要大小。比如:

   

  int *p;

  p = new int; //返回类型为int* 类型(整数型指针),分配大小为 sizeof(int);

  或:

  int* parr;

  parr = new int [100]; //返回类型为 int* 类型(整数型指针),分配大小为 sizeof(int) * 100;

 

    而 malloc 则必须由我们计算要字节数,并且在返回后强行转换为实际类型的指针。

   int* p;

  p = (int *) malloc (sizeof(int));

 

  第1、malloc 函数返回的是 void * 类型,如果你写成:p = malloc (sizeof(int)); 则程序无法通过编译,报错:“不能将 void* 赋值给 int * 类型变量”。所以必须通过 (int *) 来将强制转换。

  第2、函数的实参为 sizeof(int) ,用于指明一个整型数据需要的大小。如果你写成:

  int* p = (int *) malloc (1);

  代码也能通过编译,但事实上只分配了1个字节大小的内存空间,当你往里头存入一个整数,就会有3个字节无家可归,而直接“住进邻居家”!造成的结果是后面的内存中原有数据内容全部被清空。

  malloc 也可以达到 new [] 的效果,申请出一段连续的内存,方法无非是指定你所需要内存大小。

  比如想分配100个int类型的空间:

  int* p = (int *) malloc ( sizeof(int) * 100 ); //分配可以放得下100个整数的内存空间。

  另外有一点不能直接看出的区别是,malloc 只管分配内存,并不能对所得的内存进行初始化,所以得到的一片新内存中,其值将是随机的。

  除了分配及最后释放的方法不一样以外,通过malloc或new得到指针,在其它操作上保持一致。


四、动态申请数组

申请一维数组
一维数组的数组名可以看成数组起始元素的首地址,因此我定义一个int *arr的指针,分配n个大小的int型空间,写法如下:

   

#include <stdio.h> 
  #include <stdlib.h> 
   
  int main(void) 
  { 
    int n, *arr; 
   
    while (scanf("%d", &n) != EOF) { 
      arr = (int *)malloc(sizeof(int) * n); 
    } 
   
    return 0; 
  } 


申请二维数组
二维数组的数组名是其所有一维数组的首地址,因为二维数组的数组名是指针的指针,因为我定义一个row行column列的二维数组,写法如下:

 

  #include <stdio.h> 
  #include <stdlib.h> 
   
  int main(void) 
  { 
    int i, row, column, **arr; 
   
    while (scanf("%d %d", &row, &column) != EOF) { 
      arr = (int **)malloc(sizeof(int *) * row); // 分配所有行的首地址 
      for (i = 0; i < row; i ++) { // 按行分配每一列 
        arr[i] = (int *)malloc(sizeof(int) * column);   
      } 
   
      free(arr); 
    } 
   
    return 0; 
  } 


总结:

malloc()函数其实就在内存中找一片指定大小的空间,然后将这个空间的首地址范围给一个指针变量,这里的指针变量可以是一个单独的指针,也可以是一个数组的首地址,这要看malloc()函数中参数size的具体内容。我们这里malloc分配的内存空间在逻辑上连续的,而在物理上可以连续也可以不连续。对于我们程序员来说,我们关注的是逻辑上的连续,因为操作系统会帮我们安排内存分配,所以我们使用起来就可以当做是连续的。

相关文章

  • C++二分查找在搜索引擎多文档求交的应用分析

    C++二分查找在搜索引擎多文档求交的应用分析

    这篇文章主要介绍了C++二分查找在搜索引擎多文档求交的应用,实例分析了二分查找的原理与C++的实现及应用技巧,需要的朋友可以参考下
    2015-06-06
  • C++实现LeetCode(111.二叉树的最小深度)

    C++实现LeetCode(111.二叉树的最小深度)

    这篇文章主要介绍了C++实现LeetCode(111.二叉树的最小深度),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C++段错误(Segmentation fault)快速定位的解决方法

    C++段错误(Segmentation fault)快速定位的解决方法

    写过C++的朋友都知道,有时候程序编译通过,并不能代表程序就是对的,在linux下做开发时,经常会遇到跑崩溃的情况,但是在终端只会报Segmentation fault,如果工程代码量少,你还能重新debug一下慢慢找,本文给大家介绍了C++段错误的快速定位,需要的朋友可以参考下
    2024-07-07
  • C++自动生成迷宫游戏

    C++自动生成迷宫游戏

    这篇文章主要为大家详细介绍了C++自动生成迷宫游戏,运用并查集自动生成迷宫地图,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • C语言与C++动态通讯录超详细实现流程

    C语言与C++动态通讯录超详细实现流程

    这篇文章主要为大家介绍了C语言与C++动态实现通讯录,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-05-05
  • C++代码实现五子棋小游戏

    C++代码实现五子棋小游戏

    这篇文章主要为大家详细介绍了C++代码实现五子棋小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • C++使用LibCurl实现Web隐藏目录扫描功能

    C++使用LibCurl实现Web隐藏目录扫描功能

    LibCurl是一个开源的免费的多协议数据传输开源库,该框架具备跨平台性,开源免费,并提供了包括HTTP、FTP、SMTP、POP3等协议的功能,本文将给大家介绍C++使用LibCurl实现Web隐藏目录扫描功能
    2023-11-11
  • QT如何通过鼠标事件实现图片的拖动和缩放

    QT如何通过鼠标事件实现图片的拖动和缩放

    本文介绍了如何通过鼠标拖动移动图片以及使用鼠标滚轮进行图片缩放的技术实现,包括完整的解决方案,ImageWidget.h、ImageWidget.cpp和main.cpp的编写,以及详细的函数解释,如paintEvent()重绘图片,以及平滑缩放和偏移量的应用等,需要的朋友可以参考下
    2024-10-10
  • 使用c语言输出杨辉三角形的简单方法

    使用c语言输出杨辉三角形的简单方法

    这篇文章主要给大家介绍了关于如何使用c语言输出杨辉三角形的简单方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • C语言中判断int,long型等变量是否赋值的方法详解

    C语言中判断int,long型等变量是否赋值的方法详解

    声明了int ,long型等局部变量,在利用一些方法给这些变量赋值之后,想判断这些变量是不是真的被赋初值了,怎么办
    2013-07-07

最新评论