c++函数返回字符串指针

错误方案

char* testfunc1(){
    char chp[10] = "cpp";
    return chp;
}

int main(int argc, const char * argv[]) {
    // insert code here...
    char *p = testfunc1();
    printf("%s\n",p);
    p = nullptr;
    return 0;
}

在以上代码中,在函数中创建一个字符数组,直接将字符数组的名称作为char类型的指针作为返回值向外传递。

这种做法是错误的,编译器会弹出警告:Address of stack memory associated with local variable 'chp' returned。意思是将在栈上的局部变量返回了,这在c++中是不推荐的。

问题的原因在于,testfunc1中的字符数组chp属于局部变量,位于内存的栈区,因此指针*p指向的是栈里的局部变量。当函数运行结束后,该块内存是很有可能被其他代码使用,那个时候内存里存放的是什么内容就不是我们需要的了。

最后的结果是,*p一开始指向的确实是字符串数组chp所在的内存,当函数执行完,*p依旧指向那块内存,但是这块内存还是不是字符数组chp,就不一定了。

结论:c++函数不应该返回一个指向栈内变量的指针

解决的思路也很简单,函数返回一个指向非栈内变量的指针就好了,除了栈,我们其实可以人为将变量放在其他地方。

方案一:返回指向堆内变量的指针

//将字符串放在堆里
char* testfunc2(){
    char *p = new char(10*sizeof(char));
    strcpy(p, "hello!");
    return p;
}

int main(int argc, const char * argv[]) {
    // insert code here...
    char *p = testfunc2();
    printf("%s\n",p);
    delete p;
    p = nullptr;
    return 0;
}

函数testfunc2中在堆区开辟一块内存,并向其中存放字符串。这样该字符串的生命周期就与函数无关,即便函数执行完毕,*p照样指向的是该字符串。

需要注意的是堆里的数据需要手动回收,不然会造成内存泄漏。

方案二:返回指向静态变量的指针

//将字符串放在静态变量区
char* testfunc3(){
    static char p[100];
    strcpy(p, "hello!");
    return p;
}

int main(int argc, const char * argv[]) {
    // insert code here...
    char *p = testfunc2();
    printf("%s\n",p);
    p = nullptr;
    return 0;
}

函数testfunc3创建一个静态的字符串数组,该数组存放在静态变量区,生命周期与函数也无关,也能够解决问题。

需要注意的是,静态变量区的变量是唯一的,函数testfunc3被多个地方调用时用的是同一个变量,最好令该变量为常量。

方案三:返回指向全局变量的指针

//将字符串放在全局变量区
char pglobal[100];
char *testfunc4(char* s){
    strcpy(s, "hello!");
    return s;
}

int main(int argc, const char * argv[]) {
    // insert code here...
    char* p = testfunc4(pglobal);
    printf("%s\n",p);
    p = nullptr;
    return 0;
}

使用全局变量,就更暴力了!

你可能感兴趣的:(C++,c++,开发语言)