GetMemory的典型例子2010-01-13 18:24 520人阅读评论(2) 收藏举报//NO.1:程序首先申请一个char类型的指针str,并把str指向NULL(即str里存的是NULL的地址,*str为NULL中的值为0),调用函数的过程中做了如下动作:1申请一个char 类型的指针p,2把str的内容copy到了p里(这是参数传递过程中系统所做的),3为p指针申请了100个空间,4返回Test函数.最后程序把字符串hello world拷贝到str 指向的内存空间里.到这里错误出现了!str的空间始终为NULL而并没有实际的空间.深刻理解函数调用的第2步,将不难发现问题所在!void GetMemory(char *p){p = (char*)malloc(100);}void Test(void){char *str = NULL;GetMemory(str);strcpy(str, "hello world");printf(str);}//请问运行Test函数后会是什么样的结果?//NO.2:程序首先申请一个char类型的指针str,并把str指向NULL.调用函数的过程中做了如下动作:1申请一数组p[]并将其赋值为hello world(数组的空间大小为12),2返回数组名p付给str指针(即返回了数组的首地址).那么这样就可以打印出字符串"hello world"了么?当然是不能的!因为在函数调用的时候漏掉了最后一步.也就是在第2步return数组名后,函数调用还要进行一步操作,也就是释放内存空间.当一个函数被调用结束后它会释放掉它里面所有的变量所占用的空间.所以数组空间被释放掉了,也就是说str所指向的内容将不确定是什么东西.char *GetMemory(void){char p[] = "hello world";return p;void Test(void){char *str = NULL;str = GetMemory();printf(str);}//NO.3:问题同NO.1,正确答案为可以打印出hello.但内存泄漏了!void GetMemory(char **p, int num){*p = (char*)malloc(num);}void Test(void){char *str = NULL;GetMemory(&str, 100);strcpy(str, "hello");printf(str);}//NO.4:申请空间,拷贝字符串,释放空间.前三步操作都没有任何问题.到if语句里的判断条件开始出错了,因为一个指针被释放之后其内容并不是NULL,而是一个不确定的值.所以if语句永远都不能被执行.这也是著名的"野"指针问题.所以我们在编写程序释放一个指针之后一定要人为的将指针付成NULL.这样就会避免出现"野"指针的出现.有人说"野"指针很可怕,会带来意想不到的错误.void Test(void){char *str = (char*)malloc(100);strcpy(str, "hello");free(str);if (str != NULL)strcpy(str, "world");printf(str);}}void GetMemory1(char *p) {p = (char *)malloc(100); }void Test1(void){char *str = NULL;GetMemory1(str);strcpy(str, "hello world");printf(str);}//str一直是空,程序崩溃char *GetMemory2(void) {char p[] = "hello world";return p;}void Test2(void){char *str = NULL;str = GetMemory2();printf(str);}char *GetMemory3(void)return "hello world";}void Test3(void){char *str = NULL;str = GetMemory3();printf(str);}//Test3 中打印hello world,因为返回常量区,而且并没有被修改过。
Test2中不一定能打印出hello world,因为指向的是栈。
void GetMemory4(char **p, int num){*p = (char *)malloc(num);}void Test4(void){char *str = NULL;GetMemory3(&str, 100);strcpy(str, "hello");printf(str);}//内存没释放void Test5(void){char *str = (char *) malloc(100);strcpy(str, "hello");free(str);if(str != NULL)strcpy(str, "world");printf(str);}}//str为野指针,打印的结果不得而知void Test6(){char *str=(char *)malloc(100);strcpy(str, "hello");str+=6;free(str);if(str!=NULL){strcpy(str, "world");printf(str);}}//VC断言失败,运行错误另转一则:char *GetMemory3(int num){char *p = (char *)malloc (sizeof(char) * num); return p; //返回指针 p}void Test3(void){char *str = NULL;str = GetMemory3(100); //这里指针 str也和指针 p的指向一样的内存块。
strcpy(str, "hello");cout<< str << endl;free(str); //这里最终只是释放了str指向的内存块,对于str指针依然还是指向那块内存,看了一些资料说应该加一句str=0;那指针 p呢?p也依然在指向那块内存啊。
}回复:答者:wutaozhao() 信誉:100 级别:user2 日期:2007-6-29 21:42:21 id:41451636指针之间传递的就是地址,所以str和p所指向的内存块是同一个,释放其中任何一个即可答者:what_a_big() 信誉:100 级别:user1 日期:2007-6-29 21:42:21 id:41451637那指针 p呢?=================================================================== ==========after returning from GetMemory()p (局部变量)没了,那块内存还在。
现在str 指向那块内存。
看了一些资料说应该加一句str=0=================================也可以不写str=NULL,只要你不再引用str。
答者:believefym(feng) 信誉:100 级别:user5 日期:2007-6-29 21:50:38 id:41451675同一块内存,释放一次即可,只不过所有指向那块内存的指针都失效了,就像楼主代码里的p和str释放之后str就变成了野指针,加str=NULL,可以避免之后错误使用该指针,方便调试答者:lightnut() 信誉:100 级别:star1 日期:2007-6-29 22:05:48 id:414517361.函数进入Test3():char* str = NULL;======================变量变量的地址变量的值(内容)str 0x0013fe8c 02.str = GetMemory3(..)=====>char *p = (char *)malloc (sizeof(char) * num);将分配的内存起始地址(0x003a60b0)赋给栈变量p,===============================================变量变量的地址变量的值(内容)p 0x0013fda8 0x003a60b03. 从GetMemory3(..)返回, p的值(0x003a60b0)拷贝给str, 栈变量p生命结束, 释放其所占栈内存(地址0x0013fda8)=================================================变量变量的地址变量的值(内容)str 0x0013fe8c 0x003a60b04. free(str): 释放str指向的内存(0x003a60b0开始的内存空间)5. 推出Test3()后, 栈变量str生命结束, 释放其所占栈内存(地址0x0013fe8c)答者:freshui(五月的风-最近老犯困) 信誉:100 级别:user1 日期:2007-6-29 22:12:07 id:41451763呵呵 p没了已经死了:)注意看变量的作用域答者:buhaohaoxuexi() 信誉:100 级别:user1 日期:2007-6-29 22:37:00 id:41451888为什么会死呢,不是说动态分配是分配在堆上的吗?他不应该死啊。
答者:yydrewdrew(满堂花醉三千客,一剑霜寒十四州) 信誉:100 级别:user1 日期:2007-6-29 23:55:01 id:41452325char *GetMemory3(int num){char *p = (char *)malloc (sizeof(char) * num);return p; //返回指针 p}void Test3(void){char *str = NULL;str = GetMemory3(100); //调用完后p被析构,p为局部作用域存在于函数GetMemory3的栈中,当GetMemory3被调用完后,栈空间被释放,因而被析构。
strcpy(str, "hello");cout<< str << endl;free(str); //这里最好加一句str = NULL。