我只是在胡思乱想将指针传递给函数以了解它是如何工作的,然后我遇到了一些意想不到的行为。我有以下代码:
#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
应该指向谁知道在哪里。我错过了什么吗?
注意:这只是我制作的一个测试项目,我不断编写和删除代码块以测试不同的概念。所有 includes 和 using namespace std 都是为了便于使用,它不是我为任何实际用途而编写的代码,纯粹是教育性的。另外,我使用的是 MS VS 2013。
最佳答案
尝试像这样更改您的 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
之前所在的同一位置。
正如评论中所指出的,您正在观察一个未定义的行为,您绝不应该依赖它。上面的例子很好地说明了这一点。
关于c++ - 通过复制到函数将指针传递给动态分配的数组会产生意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30553456/