C--有关内存的思考

C--有关内存的思考


#include <stdio.h>
#include <stdlib.h>
#include <string.h>


//结果段错误,因为str指向空,传递的是指针变量,要传变量地址才可以
void getmemory0(char *p)
{
    p = (char *)malloc(100);
}


void test(void)
{
    char *str = NULL;
    getmemory0(str);
    strcpy(str,"hello world");
    printf("%s\n",str);
}


//结果正确,传递了指针变量的地址
void getmemory1(char **p)
{
    *p = (char *)malloc(100);
}


void test1(void)
{
    char *str = NULL;
    getmemory1(&str);
    strcpy(str,"hello");
    printf("%s\n",str);
    free(str);
}


//返回栈内存,内存在函数结束时消亡,str不指向空,但也不指向hello
//结果可能正确,也可能是乱码
char *getmemory2(void)
{
    char p[] = "hello world";
    return p;
}


void test2(void)
{
    char *str = NULL;
    str = getmemory2();
    printf("%s\n",str);
}


//str变为野指针,修改动态内存区的内容,结果可能正确,也可能错误
//后果难以预料,非常危险
void test3(void)
{
    char *str = (char *)malloc(100);
    strcpy(str,"hello");
    free(str);
    if(str != NULL)
    {
	strcpy(str,"world");
	printf("%s\n",str);
    }
}


int main(int argc, char *argv[])
{
    test();
    //test1();
    //test2();
    //test3();
    return 0;
}


分析:
1.test()中:
如果函数的参数是一个指针,不要指望用该指针去申请动态内存。原因:编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是_p,编译器使_p = p,如果函数体内的程序修改了_p的内容,就导致了p的内容作相应的修改,这就是指针可以用作输出参数的原因。但是,本例中,_p申请了新的内存,只是把_p所指向的内存地址改变了,但是p丝毫未变。所以getmemory并不能输出任何东西。
运行结果:程序崩溃,str仍然为NULL,strcpy运行错误。
2.test1()中:

如果非得要用指针参数去申请内存,那么应该传递“指向指针的指针”,即传&str。记得释放内存free(str)。

运行结果:能输出hello。

3.test2()中:
因为return语句返回了指向"栈内存"的指针,因为该内存在函数结束时自动消亡;执行str = getmemory()后,str不再是NULL指针,但str的内容也不再是“hello world”。
运行结果:可能是乱码,也可能是正确,str的内容是垃圾。
4.test3()中:
if(str != NULL)进行防错处理是没有用的,因为free/delete只是把指针所指向的内存给释放掉了,但并没有干掉指针本身,str被free以后,其地址仍不变(非NULL),只是该地址对应的内存是未知的,str成了野指针。
运行结果:出错,改动动态内存区的内容,后果难以预料,非常危险。
posted @ 2016-07-05 21:29  书灯  阅读(4)  评论(0)    收藏  举报  来源