通过复制到函数将指针传递给动态分配的数组具有意外结果

时间:2015-05-31 03:12:01

标签: c++ arrays pointers memory dynamic

我只是乱七八糟地传递指向函数的指针,以了解它是如何工作的,我遇到了一些意想不到的行为。我有以下代码:

#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。

1 个答案:

答案 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之前居住的同一位置分配。

正如评论中所指出的,您正在观察未定义的行为,您绝不应该依赖它。上面的例子很好地说明了这一点。