第八节 内存分配与内存释放

来源:互联网 发布:centos下安装chrome 编辑:程序博客网 时间:2024/06/05 19:51
第八节  内存分配与内存释放

1.1      malloc
1.       32 位系统下, C++程序,请计算 sizeof  的值 
char str[] = http://www.ibegroup.com/ ;
char *p = str ;
int n = 10;
请计算
sizeof (str ) =  ?(1)
sizeof ( p ) =  ?(2)
sizeof ( n ) =  ?(3)
void Foo ( char str[100]){
}
请计算
sizeof( str ) =  ?(4)
void *p = malloc( 100 );
请计算
sizeof ( p ) =  ?(5)
答案是:
(1).25   (2).4   (3).4   (4).4   (5).4
不管是int *还是char *指针,指针长度都是4.有了这点sizeof(p) = 4应该就没有任何问题了。sizeof(n) = 4 , 因为整型长度为4。剩下sizeof(str)了,我们把char str[100]变下形你可能就知道了,其实char str[100]和*(str+100)是等效的,也就是说传进去的是指针,而不是数组,那么sizeof(str) = 4就应该可以理解了。
2.   如程序清单8. 1所示,请问运行Test函数会有什么样的结果?
程序清单8. 1  malloc()的应用1
void GetMemory(char *p)
{
    p = (char *)malloc(100);
}
void Test(void)
{
    char *str = NULL;
    GetMemory(str);
    strcpy(str, "hello world");
    printf(str);
}
我敢说很多人看到这里会冒出来的答案是: hello world 。实际上答案是:NULL 。是不是傻眼了。程序意图很简单,想通过GetMenory这个函数改变str的值。事实上,GetMemory( char *p )函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入实参的值,执行完 char *str = NULL; GetMemory( str );这2条程序后的str仍然为NULL 。

3.   如程序清单8. 2所示,请问运行Test函数会有什么样的结果?
程序清单8. 2  malloc()的应用2
char *GetMemory(void)
{
    char p[] = "hello world";
    return p;
}
void Test(void)
{
    char *str = NULL;
    str = GetMemory();
    printf(str);
}
这个是hello world 了吧 !这个还真不是输出hello world 。有同学就要问了,str = GetMemory(),而Getmemory()函数返回的是p , 而p[] = "hello world " ,怎么可能不是hello world ! 实际上,p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。所以输出什么我也不知道,很可能是乱码。所以要理解变量的生存周期,否则就死翘翘了。
4.   如程序清单8. 3所示,请问运行Test函数会有什么样的结果?
程序清单8. 3  malloc()的应用3
void GetMemory(char **p, int num)
{
    *p = (char *)malloc(num);
}
void Test(void)
{
    char *str = NULL;
    GetMemory(&str, 100);
    strcpy(str, "hello");
    printf(str);
}
有些人到这里不敢吭声了,这个会是输出什么?答案是:hello。这个题目我不分析,结合上面2题请读者自己分析下。
5.         如程序清单8. 4所示,请问这个会是输出什么?
程序清单8. 4  malloc()的应用4
#include <stdio.h>
char *str()
{
    char *p = "abcdef";
    return p;
}
int main(int argc, char *argv[])
{
    printf("%s", str());
    return 0;
}
乍眼一看,在哪里见过?是的,确实似曾相识。有记忆了吧,会不会有人立马说出答案:输出乱码?
char *GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}
上面这个题目的答案确实是:乱码!
但是char *p = "abcdef";和char p[] = “abcdef”是有区别的。char *p = "abcdef"这个程序的正确答案是输出:abcdef。
为什么?是的,有人会说,你不是说数组是可以退化成指针吗?但是,你要知道,数组是存储在栈中,p[] = “abcdef”实在执行这条语句时,abcdef才会赋给p[],并且栈在执行完成之后是会自动销毁;但是指针是保存在堆中,当开辟了*p这个地址的时候,abcdef就已经存储在p中,然而堆只有在程序结束之后才会销毁,所以是可以输出abcdef这个字符串。
1.2      malloc(0)
1.         把这个独立开来是因为很少这样使用,但是又会使用。如程序清单8. 5所示,程序会输出什么?
程序清单8. 5  malloc(0)
int main(int argc, char *argv[])
{
    char *ptr = NULL;
    if ((ptr = (char *)malloc(0)) == NULL)
{
       printf("Null pointer\n");
       printf("ptr = %#x\n", ptr);
    }  
else
{
       printf("Valid pointer\n");
       printf("ptr = %#x\n", ptr);
    }
    return 0;
}
我想很多人的第一个感知是输出:Null pointer!
但是很遗憾,是输出Valid pointer!虽然ptr所开辟的内存空间为0,但是ptr是不会等于NULL的。

原创粉丝点击