zoukankan      html  css  js  c++  java
  • C语言中的malloc、new、memset函数解析

    1. malloc
    在window下,malloc的函数原型:
    extern void *malloc(unsigned int num_bytes);
    头文件:
    #include<malloc.h>或者#include<alloc.h>两者的内容是完全一样的

    • 如果分配成功:则返回指向被分配内存空间的指针
    • 不然返回指针NULL
    • 同时,当内存不再使用的时候,应使用free()函数将内存块释放掉。
      关于:void*,表示未确定类型的指针,c,c++规定void*可以强转为任何其他类型的指针,
      malloc:
    • malloc分配的内存大小至少为参数所指定的字节数
    • malloc的返回值是一个指针,指向一段可用内存的起始位置,指向一段可用内存的起始地址,多次调用malloc所分配的地址不能有重叠部分,除非某次malloc所分配的地址被释放掉malloc应该尽快完成内存分配并返回(不能使用NP-hard的内存分配算法)实现malloc时应同时实现内存大小调整和内存释放函数(realloc和free)
    • malloc和free是配对的,如果申请后不释放就是内存泄露。
      简单的说:
      malloc函数其实就是在内存中找一片指定大小的空间,然后将这个空间的首地址给一个指针变量,这里的指针变量可以是一个单独的指针,也可以是一个数组的首地址,这要看malloc函数中参数size的具体内容。

    2. new
    new返回指定类型的指针,并且可以自动计算所需要的大小。

    int *p;
    p = new int;//返回类型为int* ,分配的大小是sizeof(int)
    p = new int[100];//返回类型是int*类型,分配的大小为sizeof(int)*100
    

    而malloc需要我们自己计算字节数,并且返回的时候要强转成指定类型的指针。

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

    (1)malloc的返回是void,如果我们写成了:p=malloc(sizeof(int));间接的说明了(将void转化给了int,这不合理)
    (2)malloc的实参是sizeof(int),用于指明一个整型数据需要的大小,如果我们写成p=(int*)malloc(1),那么可以看出:只是申请了一个一个字节大小的空间。
    (3)malloc只管分配内存,并不能对其进行初始化,所以得到的一片新内存中,其值将是随机的。一般意义上:我们习惯性的将其初始化为NULL,当然也可以使用memset函数。

    3. memset函数
    在前面不止一次说过,定义变量时一定要进行初始化,尤其是数组和结构体这种占用内存大的数据结构。在使用数组的时候经常因为没有初始化而产生“烫烫烫烫烫烫”这样的野值,俗称“乱码”。

    每种类型的变量都有各自的初始化方法,memset() 函数可以说是初始化内存的“万能函数”,通常为新申请的内存进行初始化工作。它是直接操作内存空间,mem即“内存”(memory)的意思。该函数的原型为:

    # include <string.h>
    void *memset(void *s, int c, unsigned long n);
    

    函数的功能是:将指针变量 s 所指向的前 n 字节的内存单元用一个“整数” c 替换,注意 c 是 int 型。s 是 void* 型的指针变量,所以它可以为任何类型的数据进行初始化。

    memset() 的作用是在一段内存块中填充某个给定的值。因为它只能填充一个值,所以该函数的初始化为原始初始化,无法将变量初始化为程序中需要的数据。用memset初始化完后,后面程序中再向该内存空间中存放需要的数据。

    memset 一般使用“0”初始化内存单元,而且通常是给数组或结构体进行初始化。一般的变量如 char、int、float、double 等类型的变量直接初始化即可,没有必要用 memset。如果用 memset 的话反而显得麻烦。

    当然,数组也可以直接进行初始化,但 memset 是对较大的数组或结构体进行清零初始化的最快方法,因为它是直接对内存进行操作的。

    memset 函数的第三个参数 n 的值一般用 sizeof() 获取,这样比较专业。注意,如果是对指针变量所指向的内存单元进行清零初始化,那么一定要先对这个指针变量进行初始化,即一定要先让它指向某个有效的地址。而且用memset给指针变量如p所指向的内存单元进行初始化时,n 千万别写成 sizeof(p),这是新手经常会犯的错误。因为 p 是指针变量,不管 p 指向什么类型的变量,sizeof(p) 的值都是 4。

    # include <stdio.h>
    # include <string.h>
    int main(void)
    {
        int i;  //循环变量
        char str[10];
        char *p = str;
        memset(str, 0, sizeof(str));  //只能写sizeof(str), 不能写sizeof(p)
        for (i=0; i<10; ++i)
        {
            printf("%dx20", str[i]);
        }
        printf("
    ");
        return 0;
    }
    
  • 相关阅读:
    delphi调用存储过程
    mysql存储过程中使用事务
    高性能JAVA开发之内存管理
    高效的找出两个List中的不同元素
    The reference to entity "characterEncoding" must end with the ';' delimiter
    Maven的安装、配置及使用入门
    如何在电脑上测试手机网站(全)
    三种常用的js数组去重方法
    oracle ORA-01461 错误 can bind a LONG value only for insert into a LONG column
    windows cmd下netstat查看占用端口号的进程和程序
  • 原文地址:https://www.cnblogs.com/pogeba/p/14078722.html
Copyright © 2011-2022 走看看