【问题标题】:passing arrays to functions in c++将数组传递给C++中的函数
【发布时间】:2011-10-13 00:40:23
【问题描述】:

我想将一个数组传递给 C++ 中的某个函数。我写了以下代码:

#define nmpart 50

void distances( double (&dis)[3][nmpart][nmpart] )
{
    ... compute distances which are allocated in "dis"
}

double energy()
{
        double dis[3][nmpart][nmpart];

        distances(dis);
}

当 nmpart

【问题讨论】:

  • 您确定需要这么大的数组吗?当 nmpart=50000 时,您将拥有 50000*50000*3*sizeof(double),即 60 GB。使用动态分配只会让事情变得更糟,因为它需要额外的空间用于控制结构。如果数组只是部分填充,稀疏数组会更好。如果没有,也许可以更改您的算法以按需计算距离。

标签: c++ arrays function memory-management


【解决方案1】:

现在,很多人(包括我自己)永远不会专业地(或以其他方式)编写此代码,但它基本上回答了您的问题。请参阅下文,了解为什么我从不专业地写这篇文章。

#define nmpart 50  

void distances( const double ***dist) 
{     
    ... compute distances which are allocated in "dis" 
}  

double energy()
{ 
     double ***dis;

     // allocate dis
     dis = new double**[3];
     for(int i=0;i<3;++i)
     {
         dis[i] = new double*[nmpart];
         for(int j=0;j<nmpart;++j)
         {
              dis[i][j] = new double[nmpart];
         }
     }

     // code where you populate dis
     // HERE

     distances(dis);

     // deallocate dis
     for(int i=0;i<3;++i)
     {
         for(int j=0;j<nmpart;++j)
         {
              delete [] dis[i][j];
         }
         delete [] dis[i];
     }
     delete [] dis;

} 

基本上,我永远不会写这个(除了用于教学目的),因为如果在这个函数的某个地方抛出异常,那么它就会泄漏内存。最好的办法是将堆分配和释放(分别使用newdelete)包装在一个类中,并将该类放在energy() 函数内的本地堆栈中。

理想情况下你会这样做:

#define nmpart 50    

void distances( const distClass &dis)  
{          
   ... compute distances which are allocated in "dis"  
}

double energy() 
{  
    distClass dis;
    // this allocate wraps the for loops with the new []'s above
    dis.Allocate(3, nmpart , nmpart);  

    // populate dis HERE

    distances(dis);

    // when dis goes out of scope its destructor
    // is called, which wraps the for loops with the delete []'s
}

【讨论】:

    【解决方案2】:

    您可以使用 std::vector 代替。这允许动态分配。

    void distances( std::vector< std::vector< std::vector<double> > > const& dis )
    {
        ... compute distances which are allocated in "dis"
    }
    
    double energy()
    {
        std::vector< std::vector< std::vector<double> > > dis;
    
        distances(dis);
    }
    

    【讨论】:

    • 如何使用 std::vector 设置数组 [3][nmpart][nmpart] 的大小?
    • 嗯...虽然这在技术上是 OP 问题的动态版本,但我想说任何涉及向量向量向量的解决方案都有点损坏:-) 单个数组怎么样还是大步访问向量?
    • 您可以对第一个元素使用 dis.resize(3),然后使用 for (i=0;i
    • @Kerrek SB,我不是在争论,但您为什么认为任何涉及向量向量损坏的解决方案?
    • @ChrisA.:这太过分了。进行如此多的分配是不健康的。跨步访问的平面向量可为您提供更好的内存局部性和更少的分配。
    猜你喜欢
    • 2018-11-14
    • 2012-07-25
    • 2011-11-08
    • 1970-01-01
    • 1970-01-01
    • 2013-06-26
    相关资源
    最近更新 更多