经典笔试真题讲解1

题目一:

void GetMemory(char*p){
    p=(char*)malloc(100);
}
void Test(void){
    char*str=NULL;
    GetMemory(str);
    strcpy(str,"hello world");
    printf(str);
}

请问运行Test函数会有什么样的结果?

答案:非法访问

【解析】进入Test函数之后,先初始化了str的指针指向NULL,后调用了GetMemory函数,跳出函数后,进行字符串拷贝后打印。有人觉得传参没有问题,动态开辟也没有问题,那么问题在哪呢?

问题在于GetMemory调用后,并没有将str的地址传过去,所以并不能改变str的信息,char*p只是str的一份临时拷贝,Getmemory函数中为p动态开辟了一份空间,p指向了这份空间的首地址,但函数结束后这份动态开辟的空间就会被释放,str没有发生任何改变,还是指向空指针。这是用strcpy函数对str解引用后赋值,就是非法访问了。

如果要修改的话,我们可以这样做:

void GetMemory(char**p){//二级指针接受指针的地址
    *p=(char*)malloc(100);
}
void Test(void){
    char*str=NULL;
    GetMemory(&str);//将str指针的地址传过去
    strcpy(str,"hello world");
    printf(str);
}

题目二:

char*GetMemory(void){
    char p[]="hello world";
    return p;
}
void Test(void){
    char*str=NULL;
    str=GetMemory();
    printf(str);
}

请问调用Test函数会发生什么样的结果?

答案:打印乱码

【解析】进入Test函数之后,初始化了str指针指向空,后调用GetMemory函数,GetMemory函数返回了字符串的首地址,之后打印。那么有什么问题呢?

问题在于,程序运行完后p数组被销毁,而此时str指向了该空间的首地址,销毁后str成了野指针,在打印后只会打印出乱码。这是典型的返回栈空间地址的问题,在操作系统中一共有三个区域,分别是堆区、栈区和静态区。

栈区存储局部变量、函数形式的参数等;

堆区存储malloc、free、realloc的动态内存;

静态区存储全局变量、静态变量;

我们的p存储在栈区中,栈空间地址在函数结束后会被释放。所以str最终成了野指针。


题目三:

void GetMemory(char**p,int num){
    *p=(char*)malloc(num);
}
void Test(void){
    char*str=NULL;
    GetMemory(&str,100);
    strcpy(str,"hello");
    printf(str);
}

请问运行Test函数会有什么样的后果?

答案:内存泄漏

【解析】通过我们之前将的动态内存管理直到,动态开辟的内存使用后必须free掉,否则会发生内存泄漏,程序报错。所以我们只需要在print发(str)后加上free(str);str=NULL;就可以了。


题目四:

void Test(void){
    char*str=(char*)maloc(100);
    strcpy(str,"hello");
    free(str);
    if(str!=NULL){
        strcpy(str,"world");
        printf(str);
    }
}

请问运行Test函数会有什么样的结果?

答案:非法操作

【解析】在if语句之前,就已经将str的空间释放掉了,那么str就成为了一个野指针。此时进入if语句,将“world”拷贝到str里面,解引用野指针就会报错,即非法操作。

我们可以这样修改:

void Test(void){
    char*str=(char*)malloc(100);
    strcpy(str,'"hello");
    if(str!=NULL){
        strcpy(str,"world");
        printf(str);
    }
    free(str);
    str=NULL;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

妮妮妮妮没事吧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值