我只是乱七八糟地传递指向函数的指针,以了解它是如何工作的,我遇到了一些意想不到的行为。我有以下代码:
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <cmath>
#include <iomanip>
using namespace std;
struct t
{
string x;
string y;
};
void foo(t*);
int main()
{
t* ts = new t[2];
ts[0].x = "t1.x";
ts[0].y = "t1.y";
ts[1].x = "t2.x";
ts[1].y = "t2.y";
foo(ts);
cout << ts[0].x << endl;
}
void foo(t* s)
{
delete[] s;
s = new t[2];
s[0].x = "FOO.X";
s[1].y = "FOO.Y";
}
有趣的是,这里的输出是"FOO.X"
。我预计,因为在foo
内部,s
是指针ts
的副本,当我delete[] s
我有效delete[] ts
时,它们都指向同一个地址。然后s = new t[2];
应该对ts
没有影响。在foo
返回后,我将无法再访问s
或其指向的数组,而ts
应指向谁知道何处。我错过了什么吗?
注意:这只是我在我不断编写和擦除代码块以测试不同概念的测试项目。所有包含和使用命名空间std都是为了易于使用,它不是我为任何实际用途编写的代码,纯粹是教育性的。另外,我正在使用MS VS 2013。
答案 0 :(得分:1)
尝试像这样更改你的foo()并查看结果:
void foo(t* s)
{
delete[] s;
// Additional memory allocation
t* u = new t[2];
s = new t[2];
s[0].x = "FOO.X";
s[1].y = "FOO.Y";
}
通过添加另一个内存分配,我将s
移动到内存中的另一个位置,该位置不再与ts
重叠。否则,s
只是在ts
之前居住的同一位置分配。
正如评论中所指出的,您正在观察未定义的行为,您绝不应该依赖它。上面的例子很好地说明了这一点。