请问运行Test函数后会是什么样的结果?
NO.1
void GetMemory(char *p)
{
p = (char*)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}
NO.1:程序首先申请四个字节的栈空间,存放一个char类型的指针str,并把str指向NULL(即str里存的是NULL的地址,*str为NULL中的值为0,存放str的这块内存的地址值为oxoo12ff7c),调用函数的过程中做了如下动作:
1.p入栈,申请一个char 类型的指针p,也分配四个字节的栈空间;
2.把str的内容copy到了p里(这是参数传递过程中系统所做的),P被赋str的值即此时P的值也为0,存放指针P的内存地址是0x0012ff2c;
3.为p指针申请了100个空间(将新开辟的100个字节的内存空间地址赋给P,此时P的值为0x00372b70);
4.返回Test函数.函数调用结束时str的值仍为0,str并没有得到那块100个字节的内存空间地址值!
代码2:
void GetMemory(char **p)
{
*p = (char*)malloc(100);//p = (char*)malloc(100)错误,不能将一个二级指针指向分配的内存空间地址
}
int main(int argc, char *argv[])
{
char *str = NULL;
GetMemory(&str);
strcpy(str, "Hello");
return 0;
}
str可以得到分配内存的地址值。
如下动作(内存空间状态):
1.申请了四个字节的栈空间,存放str指针,此时str的值为0,存放str的这块内存的地址值为0x0012ff7c;
2.调用函数 GetMemory,指针P入栈,也分配了四个字节的栈空间,此时P是一个二级指针,存放了指针str的地址值,即P的值是0x0012ff7c,存放指针P的内存空间的地址值是0x0012ff2c;
3.将新开辟的100个字节的内存空间地址值0x00372b70赋给*P,即str,所以str的值为 0x00372b70;
4.函数返回时,str的值为分配的100个字节的内存空间的地址!
NO.3
char *GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}
NO.3:程序首先申请一个char类型的指针str,并把str指向NULL.调用函数的过程中做了如下动作:1申请一数组p[]并将其赋值为hello world(数组的空间大小为12),2返回数组名p付给str指针(即返回了数组的首地址).那么这样就可以打印出字符串"hello world"了么?当然是不能的!因为在函数调用的时候漏掉了最后一步.也就是在第2步return数组名后,函数调用还要进行一步操作,也就是释放内存空间.当一个函数被调用结束后它会释放掉它里面所有的变量所占用的空间.所以数组空间被释放掉了,也就是说str所指向的内容将不确定是什么东西.
NO.4
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:正确答案为可以打印出hello.但内存泄漏了(未被释放)!
NO.5
void Test(void)
{
char *str = (char*)malloc(100);
strcpy(str, "hello");
free(str);
if (str != NULL)
{
strcpy(str, "world");
printf(str);
}
}
NO.5:申请空间,拷贝字符串,释放空间.前三步操作都没有任何问题.到if语句里的判断条件开始出错了,因为一个指针被释放之后其内容并不是NULL,而是一个不确定的值.所以if语句永远都不能被执行.这也是著名的"野"指针问题.所以我们在编写程序释放一个指针之后一定要人为的将指针付成NULL.这样就会避免出现"野"指针的出现.有人说"野"指针很可怕,会带来意想不到的错误.