C ++中向量的动态内存分配

时间:2012-02-12 20:47:16

标签: c++

我需要编写一个函数来添加两个3D数组的元素,将结果存储在第三个3D数组中,获取结果并将它们复制到一维向量中,然后通过常量引用返回此向量。我遇到的问题是如何使用动态内存分配来返回向量,因为您无法返回局部变量。如果你可以返回一个局部变量,这就是代码的样子:

template <class T>
const vector<T>& allOperations(T*** const &x, T*** const &y, T*** &z, int height, int width, int depth)
{
    vector<T> results(height*width*depth);

    // Add the values of array x and y
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            for (int k = 0; k < depth; k++)
            {
                z[i][j][k] = x[i][j][k] + y[i][j][k];
            }
        }
    }

    int l = 0;
    //Places the values of array z into a vector 
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            for (int k = 0; k < depth; k++)
            {
                results[l] = z[i][j][k];
                l++;
            }
        }
    }
    return results;
}

这是我使用动态内存分配的错误尝试:

template <class T>
const vector<T>& allOperations(T*** const &x, T*** const &y, T*** &z, int height, int width, int depth)
{
    vector<T>* results(height*width*depth) = new vector<T>;

    // Add the values of array x and y
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            for (int k = 0; k < depth; k++)
            {
                z[i][j][k] = x[i][j][k] + y[i][j][k];
            }
        }
    }

    int l = 0;
    //Places the values of array z into a vector 
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            for (int k = 0; k < depth; k++)
            {
                *results[l] = z[i][j][k];
                l++;
            }
        }
    }
    return *results;
}

1 个答案:

答案 0 :(得分:2)

返回对局部变量的引用是没有意义的。如果你求助于你的第二个解决方案(返回对new'd向量的引用),那么你几乎肯定会有内存泄漏。按照惯例,获取引用通常意味着其他实体已经在管理返回对象的生命周期。

您可以采取多种措施来解决此问题。


不要执行动态内存分配,请更改功能签名。

// Return a copy of the vector.
vector<T> allOperations(T*** const &x, T*** const &y, T*** &z, int height, int width,  int depth)
{
    vector<T> results(height*width*depth);
    // ...
    return results;
}

如果编译器执行copy elision和/或支持C++11 move constructors,则“复制”将永远不会发生,并且返回将非常有效。


如果你真的想动态分配向量来满足其他一些约束,你还需要更改函数签名:

// Return a pointer to a newly allocated vector.
const vector<T>* allOperations(T*** const &x, T*** const &y, T*** &z, int height, int width, int depth)
{
    vector<T>* results(height*width*depth) = new vector<T>;
    // ...
    return results;
}

如果您这样做,请考虑返回smart pointer而不是返回裸指针。


如果这是一个成员函数,那么也许你可以将向量存储在对象中。

template<typename T>
class SomeClass
{
    std::vector<T> results;
public:
    // ...

    // Modify member and return reference to internal member.
    const vector<T>& allOperations(T*** const &x, T*** const &y, T*** &z, int height, int width,  int depth)
    {
        results.resize(height*width*depth);
        // ...
        return results;
    }
};

另一种可能的,但强烈反对解决方案是返回对某个全局变量的引用。

std::vector<T> results;

// Modify global and return reference to global variable.
const vector<T>& allOperations(T*** const &x, T*** const &y, T*** &z, int height, int width,  int depth)
{
    results.resize(height*width*depth);
    // ...
    return results;
}

或者,以其伪装(但完全相同)的形式:

// Modify global and return reference to global variable.
const vector<T>& allOperations(T*** const &x, T*** const &y, T*** &z, int height, int width,  int depth)
{
    // Global variable with name not visible outside the function.
    static std::vector<T> results;

    results.resize(height*width*depth);
    // ...
    return results;
}