我有这段代码:
#include <iostream>
using namespace std;
char* pass(char* p){
char* a = new char[10];
a[0] = 'S';
a[1] = 'e';
a[2] = 'r';
a[3] = 'g';
a[3] = 'e';
a[3] = 'y';
a[4] = '\0';
p = a;
//delete [] a;
return p;
}
int main(int argc,char* argv[]){
char* p1 = new char[1000];
p1[0] = 'G';
p1[1] = 'e';
p1[2] = 'r';
p1[3] = 'y';
p1[4] = '\0';
char* p2 = p1;
cout << p2 << endl;
cout << pass(p2) << endl;
delete [] p1;
}
,输出为:
Gery
Sery
但如果我取消注释delete [] a
行
我得到了这个输出:
Gery
ê§É
为什么?
答案 0 :(得分:2)
在此功能中
char* pass(char* p){
char* a = new char[10];
a[0] = 'S';
a[1] = 'e';
a[2] = 'r';
a[3] = 'g';
a[3] = 'e';
a[3] = 'y';
a[4] = '\0';
p = a;
//delete [] a;
return p;
}
参数是函数的局部变量。退出该功能后,它将被销毁。
您可以通过以下方式想象函数及其调用
pass(p2);
char* pass(/*char* p*/){
char* p = p2;
char* a = new char[10];
a[0] = 'S';
a[1] = 'e';
a[2] = 'r';
a[3] = 'g';
a[3] = 'e';
a[3] = 'y';
a[4] = '\0';
p = a;
//delete [] a;
return p;
}
如您所见,原始指针p2
将不会在函数中更改。该函数更改其声明为参数的局部变量p
。
如果取消注释delete语句,则返回值指向的内存将被删除,返回的指针将无效。在这种情况下,由于语句
,程序具有未定义的行为cout << pass(p2) << endl;
尝试使用函数的返回值访问已删除的内存。
因此没有意义返回指向已删除内存的指针。
您想要做的事情可以通过三种方式实现
第一个是将参数声明为参考
char* pass(char* &p){
^^^^^^^^
char* a = new char[10];
a[0] = 'S';
a[1] = 'e';
a[2] = 'r';
a[3] = 'g';
a[3] = 'e';
a[3] = 'y';
a[4] = '\0';
p = a;
return p;
}
并调用函数
cout << pass(p2) << endl;
第二个是将参数声明为指向间接接受原始指针的指针
char* pass(char* *p){
^^^^^^^^
char* a = new char[10];
a[0] = 'S';
a[1] = 'e';
a[2] = 'r';
a[3] = 'g';
a[3] = 'e';
a[3] = 'y';
a[4] = '\0';
*p = a;
^^^^^^^^
return *p;
^^^^^^^^^^
}
并调用函数
cout << pass(&p2) << endl;
最后你可以简单地将返回的值分配给原始指针。例如
char* pass(char* p){
char* a = new char[10];
a[0] = 'S';
a[1] = 'e';
a[2] = 'r';
a[3] = 'g';
a[3] = 'e';
a[3] = 'y';
a[4] = '\0';
p = a;
return p;
}
并将函数调用为
cout << ( p2 = pass(p2) ) << endl;
虽然在这种情况下参数已过时。
在任何情况下,您都应该删除程序末尾的已分配内存,如
delete [] p2;
答案 1 :(得分:1)
p = a
不会复制值。
您正在寻找的可能是:
memcpy(p, a, 10*sizeof(char));
答案 2 :(得分:0)
因为您的未注释行会释放您返回的内存,而您的编译器(可能作为调试辅助工具)会覆盖已释放的内存。
您的p
按值传递,因此p = a;
实际上并未在主内部更改p1
。您基本上初始化内存,删除它,然后返回指向已删除内存的指针。
如果没有额外删除,您只需泄漏该内存。