函数调用
函数调用可能引发的问题
1.
#include <stdio.h> #include <stdlib.h> #include <string.h> void getmemory(char *p, int num) { p = (char *)malloc(num); } int main() { char *str = NULL; getmemory(str, 100); strcpy(str, "hello"); printf("%s\n", str); return 0; }
传入getMemory(char *p, int num)函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入形参的值,执行完
char *str = NULL; GetMemory( str );
后的str仍然为NULL;
毛病出在函数GetMemory 中。
编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是 _p,编译器使 _p = p。
如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改。
这就是指针可以用作输出参数的原因。
在本例中,_p申请了新的内存,只是把 _p所指的内存地址改变了,但是p丝毫未变。
所以函数GetMemory并不能输出任何东西。事实上,每执行一次GetMemory就会泄露一块内存,因为没有用free释放内存。
程序会在
strcpy(str,"hello");
这段代码运行错误。
2.malloc后没有判断非空
3.最好使用strncpy,控制copy的个数
4.申请内存没有释放
函数最后可以修改为:
#include <stdio.h> #include <stdlib.h> #include <string.h> void getmemory(char **p, int num) { *p = (char *)malloc(num); } int main() { char *str = NULL; getmemory(&str, 100); strcpy(str, "hello"); printf("%s\n", str); return 0; }
1.能够输出hello
2.Test函数中也未对malloc的内存进行释放。
3. GetMemory避免了1的问题,传入GetMemory的参数为字符串指针的指针,但是在GetMemory中执行申请内存及赋值语句
*p = (char *) malloc( num );
后未判断内存是否申请成功,应加上:
if ( *p == NULL )
{
...//进行申请内存失败处理
}
&str是指针的地址,将指针的地址传给形参p,则p也指向str,
所以*p = (char *)malloc(sizeof(char) * num);也就是给p所指向的str分配了内存,所以正确。
2.
char *getMemory( void ) { char p[] = "hello world"; return p; } int main( void ) { char *str = NULL; str = getMemory(); printf( str ); return 0; }
可能是乱码。
char p[] = "hello";
return p;
p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。
3.
int main(void) { char *str = (char *) malloc(100); strcpy(str, “hello”); free(str); if(str != NULL) { strcpy(str, “world”); printf(str); } return 0; }
char *str = (char *) malloc(100);
后未进行内存是否申请成功的判断;
另外,在free(str)后未置str为空,导致可能变成一个“野”指针,应加上:
str = NULL;
4.
char *getString(void) { char *p = "hello world"; return p; } int main(void) { char *str = NULL; str = getString(); cout<< str << endl; return 0; }
函数运行虽然不会出错,但是函数GetString的设计概念却是错误的。
因为GetString内的“hello world”是常量字符串,位于静态存储区,它在程序生命期内恒定不变。
无论什么时候调用GetString,它返回的始终是同一个“只读”的内存块。
5.
void test(void) { char *p = (char *) malloc(100); strcpy(p, “hello”); free(p); // p 所指的内存被释放,但是p所指的地址仍然不变 … if(p != NULL) // 没有起到防错作用 { strcpy(p, “world”); // 出错 } }
6.
char *getMemory(void) { return "hello world"; } int main(void) { char *str = NULL; str = GetMemory3(); printf(str); return 0; }
正确打印hello world, 字符串在常量区
7.
char *GetMemory(int num) { char *p = (char *)malloc(sizeof(char) * num); return p; } int main(void) { char *str = NULL; str = GetMemory3(100); strcpy(str, "hello"); cout<< str << endl; free(str); return 0; }
正确打印hello world
8.
void swap( int* p1,int* p2 ) { int *p; *p = *p1; *p1 = *p2; *p2 = *p; } //在swap函数中,p是一个“野”指针,有可能指向系统区,导致程序运行的崩溃。 //应该改为 void swap( int* p1,int* p2 ) { int p; p = *p1; *p1 = *p2; *p2 = p; }
参考:
https://blog.csdn.net/yangtrees/article/details/8923350
https://blog.csdn.net/u012199908/article/details/78607432?utm_source=blogxgwz1