zoukankan      html  css  js  c++  java
  • C内存分配的学习

    C内存分配的学习

    内存分配方式有三种

    (1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的 整个运行期间都存在。例如全局变量,static 变量。 

    (2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函 数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 

    (3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多 少的内存,程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期 由我们决定,使用非常灵活,但问题也最多。 


    void GetMemory(char *p) 

         p = (char *)malloc(100); 

    void Test(void) 

        char *str = NULL; 
        GetMemory(str); 
        strcpy(str, "hello world"); 
        printf(str); 


    请问运行Test函数会有什么样的结果? 

    答:程序崩溃。 

    因为GetMemory并不能传递动态内存,Test 函数中的str一直都是 NULL。 

    strcpy(str,"hello world");将使程序崩溃。 

    测试结果:

    char*GetMemory(void) 

        char* p = "hello world"; 
        return p; 

    void Test(void) 

        char *str = NULL; 
        str = GetMemory(); 
        printf(str); 

    请问运行Test 函数会有什么样的结果? 
    答:可能是乱码。 

    因为GetMemory 返回的是指向“栈内存” 的指针,该指针的地址不是 NULL,但其原 现的内容已经被清除,新内容不可知。 

    voidGetMemory2(char **p, int num) 

        *p = (char *)malloc(num); 

    void Test(void) 

        char *str = NULL; 
        GetMemory(&str, 100); 
        strcpy(str, "hello"); 
        printf(str); 


    请问运行Test 函数会有什么样的结果? 
    答: 
    (1)能够输出hello 
    (2)内存泄漏 
    请问运行Test 函数会有什么样的结果? 
    答:篡改动态内存区的内容,后果难以预 料,非常危险。 因为free(str);之后,str 成为野指针, if(str !=NULL)语句不起作用。 

    //--------------------------------------------------------------------------------

    voidGetMemory2(char **p, int num) 

        *p = (char *)malloc(sizeof(char) * num); 

    void Test2(void) 

        char *str = NULL; 
        GetMemory2(&str, 100); // 注意参数是 &str,而不是str 
        strcpy(str, "hello"); 
        cout<< str << endl; 
        free(str); 

    如果非得要用指针参数去申请内存,那么应该改用“指向指针的指针”.由于“指向指针的指针”这个概念不容易理解,我们可以用函数返回值来传递动态内存。 

    //这样写也是可以的
    char *GetMemory3(int num) 

         char *p = (char *)malloc(sizeof(char) * num); 
         return p; 

    voidTest3(void) 

         char *str = NULL; 
         str = GetMemory3(100); 
         strcpy(str, "hello"); 
         cout<< str << endl; 
         free(str); 

    用函数返回值来传递动态内存这种方法虽然好用,但是常常有人把return 语句用错 了。这里强调不要用return 语句返回指向“栈内存”的指针,因为该内存在函数结束时 自动消亡

    //--------------------------------------------------------------------------------

    char *GetString(void) 

         char *p = "hello world"; //这时指向的是栈内存
         return p; // 编译器将提出警告 

    void Test4(void) 

         char *str = NULL; 
         str = GetString(); // str 的内容是垃圾 
         cout<< str << endl; 


    用调试器逐步跟踪Test4,发现执行str = GetString 语句后str 不再是NULL 指针, 
    但是str 的内容不是“hello world”而是垃圾。

    char*GetString2(void) 

         char *p = "hello world"; 
         return p; 

    void Test5(void) 

         char *str = NULL; 
         str = GetString2(); 
         cout<< str << endl; 

    函数Test5 运行虽然不会出错,但是函数GetString2 的设计概念却是错误的。因为 GetString2内的“hello world”是常量字符串,位于静态存储区,它在程序生命期内 恒定不变。无论什么时候调用GetString2,它返回的始终是同一个“只读”的内存块。强行赋值的话会出现错误。

  • 相关阅读:
    c#报错信息 显示详细行号
    分析器错误消息: “webgroup.admin.index”不扩展类“System.Web.UI.Page”,因此此处不允许
    ASP.NET下AJAX.AJAXMETHOD使用方法,微软ajax 异步 同步的修改方法
    Jquery实际应用,判断radio,selelct,checkbox是否选中及选中的值,jquery如果获取多个重复name的input的值
    utf8编码的mysql数据库 按照 中文来对 名称进行排序
    MVC新手教程二:Action使用非默认视图,强类型和强类型视图
    gcc 编译多个源文件
    嵌入式学习路径
    C语言基础知识:printf的输出格式
    C语言的数据类型
  • 原文地址:https://www.cnblogs.com/yixiaoyang/p/1901125.html
Copyright © 2011-2022 走看看