C语言中的函数参数传递都是传值操作,所以要使被调用函数改变调用函数的属性内容,则需要传递所需修改属性的指针——属性地址。
例1:
- void GetMemory( char *p)
- {
- p = (char *)malloc(100);
- }
- void Test( void )
- {
- char *str = NULL;
- GetMemory(str);
- strcpy(str, "hello world" );
- printf(str);
- }
请问运行Test 函数会有什么样的结果?
答: 因为GetMemory函数接收的是str指针的拷贝 ,所以,当其退出时,str的拷贝p在栈中的内容会被释放,并且以上操作对Test 函数中的str没有影响, str一直都是 NULL , strcpy(str, "hello world"); 将使 程序崩溃。
例2:
- Void GetMemory2( 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 )内存泄漏
原因:以上两个对照说明形参只能传递地址不能传递值。
例3:
- char *GetMemory( void )
- {
- char p[] = "hello world" ; //此行将p[]改成*p就对了,此时p[]存在
- return p; //于栈里边,*p的话字符串存于常量区
- }
- void Test( void )
- {
- char *str = NULL;
- str = GetMemory();
- printf(str);
- }
请问运行Test 函数会有什么样的结果?
请问运行Test 函数会有什么样的结果?
答: 可能是乱码。 因为GetMemory 返回的是指向“栈内存”的指针,该指针的地址不是 NULL ,但其原现的内容已经被清除,新内容不可知。
例4:
- void Test( void )
- {
- char *str = ( char *) malloc(100);
- strcpy(str, “hello”);
- free(str);
- if (str != NULL)
- {
- strcpy(str, “world”);
- printf(str);
- }
- }
答:篡改动态内存区的内容,后果难以预料,非常危险。
因为free(str); 之后,str 成为野指针,
if(str != NULL) 语句不起作用。谨记malloc之后一定记得free,free之后将指针NULL一下,以免形成野指针。
以下摘自其他地方:
例5:
- void GetMemory( char **p, int num)
- {
- /*p,指向指针的指针,*p,p指向的指针(即str),**p,最终的对象,str指向的单元*/
- *p=(char *)malloc(num);
- //申请空间首地址付给传入的被p指向的指针,即str
- }
- int main()
- {
- char *str=NULL;
- GetMemory(&str,100); //传入指针变量本身的地址
- strcpy(str,"hello" );
- free(str);
- if (str!=NULL)
- {
- strcpy(str,"world" );
- }
- printf("/n str is %s" ,str); 软件开发网 www.mscto.com
- getchar();
- }
问输出结果是什么?
答案:输出str is world。
free 只是释放的str指向的内存空间,它本身的值还是存在的.所以free之后,有一个好的习惯就是将str=NULL.此时str指向空间的内存已被回收, 如果输出语句之前还存在分配空间的操作的话,这段存储空间是可能被重新分配给其他变量的,尽管这段程序确实是存在大大的问题(上面各位已经说得很清楚 了),但是通常会打印出world来。这是因为,进程中的内存管理一般不是由操作系统完成的,而是由库函数自己完成的。当你malloc一块内存的时候, 管理库向操作系统申请一块空间(可能会比你申请的大一些),然后在这块空间中记录一些管理信息(一般是在你申请的内存 前面一点),并将可用内存的地址返回。但是释放内存的时候,管理库通常都不会将内存还给操作系统,因此你是可以继续访问这块地址的。
free 只是释放的str指向的内存空间,它本身的值还是存在的.所以free之后,有一个好的习惯就是将str=NULL.此时str指向空间的内存已被回收, 如果输出语句之前还存在分配空间的操作的话,这段存储空间是可能被重新分配给其他变量的,尽管这段程序确实是存在大大的问题(上面各位已经说得很清楚 了),但是通常会打印出world来。这是因为,进程中的内存管理一般不是由操作系统完成的,而是由库函数自己完成的。当你malloc一块内存的时候, 管理库向操作系统申请一块空间(可能会比你申请的大一些),然后在这块空间中记录一些管理信息(一般是在你申请的内存 前面一点),并将可用内存的地址返回。但是释放内存的时候,管理库通常都不会将内存还给操作系统,因此你是可以继续访问这块地址的。
转载自:[http://lhg803.javaeye.com/blog/417858]