【问题标题】:2D dynamically allocated global array in C++ Intel Parallel Studio 2015C++ Intel Parallel Studio 2015 中的二维动态分配全局数组
【发布时间】:2017-12-19 23:08:08
【问题描述】:

所以我利用这个网站获得了我认为正确的语法,但我仍然卡住了。

我在我的项目中引入了一些预先存在的快速哈特利变换代码,这些代码目前使用 FFT,除了 FHT 的大小和重叠是硬编码的之外,所有这些都可以工作,我想在我的 FFT 代码中使用这些值在运行时动态设置大小。

这需要二维全局数组。

所以我在任何函数之外定义数组,以便全局:

`double         **mInput;`

在初始化函数中我这样做:

`

kWindowSize = (int)fftlen; //fftlen is a global from my existing program
mInput = new double*[kWindowSize];
    for (int i = 0; i < kWindowSize; ++i)
        mInput[i] = new double[2];

    printf("\nmInput pointer: %x mInput value: %f", (void *)&mInput, mInput);
    printf("\nfirst sample: %f second sample %f", mInput[0][0], mInput[0][1]);`

在另一个函数中编译和运行良好:

`printf("\n\n\n-->mInput pointer: %x mInput value: %f", (void *)&mInput, mInput);
    printf("\n-->first sample: %f second sample %f", mInput[0][0]);
    printf("\n-->second sample %f", mInput[0][1]);`

它在第二个 printf 状态(尝试访问 2d 数组中的值)崩溃,并非法写入位置零。

似乎 for 循环中的新语句是在创建本地数组而不是全局数组?

自从我从这里得到动态分配语法后,我开始怀疑这是否是 intel 编译器中的错误?

建议?

谢谢!

【问题讨论】:

  • 有什么理由不使用std::vector&lt;std::vector&lt;double&gt;&gt; 而不是double **
  • printf 期望%f 时传递mInput 是不好的。 printf("\n--&gt;first sample: %f second sample %f", mInput[0][0]); 在这种情况下 printf 需要两个参数。
  • “这需要二维全局数组”——谁说的?如果你足够想要全局变量,总是可以避免的。
  • new double[2]?真的吗?
  • printf 仅用于调试。第一次将 mInput 写入 init 函数外部时,代码会崩溃。

标签: c++ arrays multidimensional-array dynamic global


【解决方案1】:

我采用了您对全局 2D 数组或双指针的想法,并且在不使用 vectorlistarray 的情况下这样做可能会对您有所帮助,但将其包装到模板类结构中使用智能指针。我做过这样的事情:

#include <memory>
template <typename T = double>
struct Buffer {
    T* ptdatafield_ { nullptr };
    T* ptdata_ { nullptr };
    Buffer();
};

template<>
Buffer<double>::Buffer() {};

template<typename T = double>
class FFTBuffer {
public: 
    std::unique_ptr< Buffer<T> > unique_ptr_buffer_ { nullptr };

    union {
        T** pprawbuffer_ { nullptr };                       

        struct {
            std::shared_ptr<T> sub_shared_BufferIndexi_;
            std::shared_ptr<T> sub_shared_BufferIndexj_;
        };

        struct {
            T* rawIndexi_;
            T* rawIndexj_;
        };
    };

    explicit FFTBuffer( const Buffer<T>& buffer );      
    ~FFTBuffer() {};
};

template<>
FFTBuffer<double>::FFTBuffer( const Buffer<double>& buffer ) :
unique_ptr_buffer_( std::make_unique<Buffer<>>( buffer ) ), 
rawIndexi_( buffer.ptdatafield_ ), rawIndexj_( buffer.ptdata_ ) {    
}

int main() {
    Buffer<> buffer;
    FFTBuffer<> fftBuffer( buffer );

    Buffer<>* pBuffer = new Buffer<>();
    FFTBuffer<> fftBuffer2( *pBuffer );

    return 0;
}

现在这段代码可以按原样编译,但我还没有用值或填充内部数组对其进行测试。我添加了公共联合与无名结构的使用。如果对齐正确,它应该与 2D 数组(例如 MxN 矩阵)中的行和列匹配。此类将unique_ptr&lt;&gt; 存储到Buffer 对象,该对象本身具有两个单独的指针,一个用于数组的每个维度。然后,它使用该Buffer 对象在其内部无名结构和双指针的公共联合中设置数据字段。这只是访问相同内存位置的多种方式。

这个想法是一般地形成这种关联......

//.....

int i, j;
(fftBuffer.unique_ptr_buffer_.get()->ptdatafield_[i], fftBuffer.unique_ptr_buffer_.get()->ptdata_[j]) =  
fftBuffer.pprawbuffer_[i][j] = 
(fftBuffer.rawIndexi_[i], fftBuffer.rawIndexj_[j] =
(fftBuffer.sub_shared_BufferIndexi_.get()[i], fftBuffer.sub_shared_BufferIndexj_.get()[j]) 

现在我没有实现或包含 [] 重载运算符或任何其他运算符,但它们应该不难实现。这应该有助于直观地了解 2D 数组是如何线性存储在内存中的,并且可以在不需要“双 for 循环”的情况下访问或分配元素。

我将不胜感激,除了任何和所有关于此算法的伪代码设计意图的反馈,并简要说明您的决定。我想听听为什么这是“好或坏”代码的利弊,在哪里可以改进其设计和实现,以及这可能带来的其他复杂性。

-- 就我个人而言,我尽量避免独立的全局变量,除非它们是永远不会改变的 const 值,或者是静态全局变量,例如指向单例类对象的静态全局指针。 --

【讨论】:

    猜你喜欢
    • 2021-02-03
    • 2015-09-17
    • 1970-01-01
    • 1970-01-01
    • 2015-02-10
    • 2013-11-14
    • 2021-12-30
    • 2017-03-11
    • 2012-02-06
    相关资源
    最近更新 更多