自动变量和开辟内存的生存期和作用域探讨
《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 }
运行结果:
‖==========钟于原创 乐于分享 宁静致远 毋忆典藏==========‖