1

当我在下面编译时,只有第一个“cout”可以正常工作。

void * functionname()
{
int i[3]={1,2,3};
int *p = i;
return p;
}

int main()
{

int *p = new int[3];
p= (int *)functionname();

std::cout<<p[1]<<"\n";
std::cout<<p[1]<<"\n";
std::cout<<p[2]<<"\n";
std::cout<<p[2]<<"\n";
std::cout<<p[3]<<"\n";
std::cout<<p[3]<<"\n";
delete [] p;
return 0;
}

你能说一下有什么问题吗?

4

4 回答 4

3

该数组i是函数的本地数组。当函数返回时它会死掉,给你留下一个悬空的指针。最好返回一个std::array.

std::array<int, 3> functionname()
{
  return std::array<int, 3>{{1,2,3}};
}

这样,调用者得到了数组的副本,就没有问题了。在开始担心复制成本之前,请注意通常编译器会忽略复制,因此只创建一个数组。

如果您需要访问底层数据块,您可以使用theArray.data()&theArray[0]。这些给你一个指向第一个元素的指针。

注意 1:如果你没有 C++11 支持,你可以std::tr1::array从头文件中使用<tr1/array>。如果您没有,请查看boost::array或推出您自己的数组类。

注意 2:如果您想要一个仅在运行时知道大小的数组,请std::vector改用。

于 2013-11-15T07:01:46.417 回答
2

将其更改为

void * functionname() {
    int *i = new int[3];
    i[0] = 1;
    i[1] = 2;
    i[2] = 3;
    return i;
}

如果数组要在函数末尾之后存在,则必须将其放在堆上而不是堆栈上。

正如@juanchopanza 和@Servé 指出的那样,为了正确的内存管理,请确保在完成后处理掉它。

int *a = (int *)functionname();
//do something with a
delete[] a;
于 2013-11-15T07:04:17.327 回答
1

您返回指向在函数退出时被销毁的临时对象的指针。

这将起作用:

void * functionname()
{
  static int i[3]={1,2,3};
  int *p = i;
  return p;
}

注意那里的“静态”。

于 2013-11-15T07:07:56.217 回答
0

您可以在下面找到一个将本地数组放到外部的版本。这个版本接近你所拥有的。您将指针传递给要填充的字段functionname。您负责复制的数组适合可用空间。

但是,现在最好将对象用于类似std::vector的东西。新的 move-constructor (c++11) 将使其更加高效。

另请注意,您的索引访问权限错误。C++ 数组从 0 开始索引,而不是从 1 开始。

#include <iostream>

void functionname(int* p)
{
    int i[3]={1,2,3};
    std::copy(i,i+sizeof(i)/sizeof(i[0]),p);
}

int main()
{

    int *p = new int[3];
    functionname(p);

    std::cout<<p[0]<<"\n";
    std::cout<<p[1]<<"\n";
    std::cout<<p[2]<<"\n";
    delete [] p;
    return 0;
}
于 2013-11-15T07:22:57.127 回答