zoukankan      html  css  js  c++  java
  • 自动变量和开辟内存的生存期和作用域探讨

      《C程序设计》谭浩强第4版针对Auto变量的生存期作用域做出了说明,包括内存管理与释放,指出“函数执行完后,会自动释放自动变量所占用的内存单元”

    做一下几种情况的讨论:

      ①函数结束后,自动变量会被释放,即便以指针的形式返回,返回后,指针地址没有变,但是,任何读取操作都会刷新这段内存到不可预知的状态。这种情况再VS2013编译的时候会有警告  warning C4172: 返回局部变量或临时变量的地址 

         ②如果使用函数返回值,可以使用malloc申请内存,操作完成后return出去,这种情况下不需要指向指针的指针,而且外部可以使用free释放掉

         ③如果企图通过单指针参数在函数内部开辟内存VS2013编译器会给出警告: warning C4700: 使用了未初始化的局部变量“pFromParameter” ,而且,运行到调用函数处会崩溃

         ④如果需要在被调函数内部malloc内存,需要使用指向指针的指针,参考:在函数体内开辟动态内存时,函数形参选择指向指针的指针的原理解析 ,参数传递相关资料参考其他网友的博客:C/C++中函数参数传递详解

         从以上内容及下文代码中的编译信息可以看出,VS2013的警告信息必须重视,应该处理到没有“警”告为止

         代码及运行结果如下(注意:为了演示,运行到第85行程序会崩溃,可以注释掉): 

     1 // CUITestingCPP.cpp : 定义控制台应用程序的入口点。
     2 //
     3 
     4 #include "stdafx.h"
     5 #include <iostream>
     6 using namespace std;
     7 
     8 typedef struct CvHistogra
     9 {
    10     int type;
    11     float** thresh2;
    12     int aas;
    13 }
    14 CvHistogra;
    15 
    16 CvHistogra * ReturnAddOfAutoVariable()
    17 {
    18     CvHistogra AutoVariable;
    19     AutoVariable.type = 2;
    20     cout << "AutoVariable变量地址:" << &AutoVariable << endl;
    21     cout << "AutoVariable成员type的值:" << AutoVariable.type << endl;
    22     return &AutoVariable; //本行报警: warning C4172: 返回局部变量或临时变量的地址
    23 }
    24 
    25 CvHistogra * ReturnMallocMemeryToPointer()
    26 {
    27     CvHistogra *  mallocPointerInFun = (CvHistogra*)malloc(sizeof(CvHistogra));
    28     mallocPointerInFun->type = 5;
    29     cout << "mallocPointerInFun变量地址:" << mallocPointerInFun << endl;
    30     cout << "mallocPointerInFun成员type的值:" << mallocPointerInFun->type << endl;
    31 
    32     return mallocPointerInFun;
    33 }
    34 
    35 //将“单”指针作为参数,企图在函数内部malloc并通过参数返回出去,错误决定,
    36 //这种单指针的传参必须传入已经拥有内存的指针,例如malloc过的、指向变量的、指向数组的
    37 //如果希望在函数内malloc,并通过参数赋值给调用函数的指针,则被调函数必须是指向指针的指针
    38 void PointerFromParameterMalloc(CvHistogra * pParameter)
    39 {
    40     pParameter = (CvHistogra*)malloc(sizeof(CvHistogra));
    41     pParameter->type = 5;
    42     cout << "pParameter变量地址:" << pParameter << endl;
    43     cout << "pParameter成员type的值:" << pParameter->type << endl;
    44 }
    45 
    46 int _tmain(int argc, _TCHAR* argv[])
    47 {
    48     //--------------------使用函数返回值的方式将自动变量的地址return出去--------------------------/:
    49 
    50     CvHistogra * pAddOfAutoVariable;
    51     pAddOfAutoVariable = ReturnAddOfAutoVariable();
    52 
    53     cout << "pAddOfAutoVariable成员type的值:" << pAddOfAutoVariable->type << endl;
    54     cout << "pAddOfAutoVariable成员type的值再输出一次值改变:" << pAddOfAutoVariable->type << endl;
    55     cout << "pAddOfAutoVariable  指针的值没有改变:" << pAddOfAutoVariable << endl;
    56 
    57     //free(histTest);
    58     //pAddOfAutoVariable所指向的内存不是malloc开辟的,是栈上的内存,所以使用free释放失败
    59 
    60     cout << endl;
    61     cout << endl;
    62 
    63     //-------------------------------------------------------------------------------------------/。
    64 
    65     //--------------------在被调用函数中malloc内存return出去--------------------------/:
    66 
    67     CvHistogra * pFromFunMalloc;
    68     pFromFunMalloc = ReturnMallocMemeryToPointer();
    69     cout << "pFromFunMalloc  指针的值:" << pFromFunMalloc << endl;
    70     cout << "pFromFunMalloc 成员type的值:" << pFromFunMalloc->type << endl;
    71     cout << "pFromFunMalloc 成员type的值再输出一次也不变:" << pFromFunMalloc->type << endl;
    72 
    73     pFromFunMalloc->aas = 9;
    74 
    75     free(pFromFunMalloc);  
    76     //函数内malloc的内存,如果是return出来的,在外部可以使用free释放
    77     pFromFunMalloc = NULL; 
    78     //释放完毕要置为null,不然下边一行还能够输出,只是输出的是错误的值
    79 
    80     //--------------------------------------------------------------------------------/。
    81 
    82     //--------------------传指针给函数参数,在被调函数中malloc内存--------------------------/:
    83 
    84     CvHistogra * pFromParameter;
    85     PointerFromParameterMalloc(pFromParameter);//本行报警,而且运行时崩溃:warning C4700: 使用了未初始化的局部变量“pFromParameter”
    86     cout << "pFromParameter  指针的值:" << pFromParameter << endl;
    87     cout << "pFromParameter 成员type的值:" << pFromParameter->type << endl;
    88 
    89     //--------------------------------------------------------------------------------/。
    90 
    91     system("pause");
    92 
    93     return 0;
    94 }

    运行结果:

  • 相关阅读:
    Windows环境中Java多个JDK之间相互切换
    百度地图调用,传递经纬度到后台
    富文本的使用-KindEditor
    Play框架的@OneToMany、@ManyToOne级联操作
    Play框架文件上传
    [20171211][转载]如何实现dbms_output输出没有打开serveroutput on.txt
    [20171211]ora-16014 11g.txt
    [20171206]rman与truncate2.txt
    [20171206]rman与truncate.txt
    [20171205]uniq命令的输入输出.txt
  • 原文地址:https://www.cnblogs.com/tingshuixuan2012/p/4485527.html
Copyright © 2011-2022 走看看