在c ++中设置任意类型的动态数组长度的通用方法

时间:2009-08-11 16:48:48

标签: c++ dynamic-data

我正在做一个将一些Pascal(Delphi)代码转换为C ++的项目,并希望编写一个大致相当于Pascal“SetLength”方法的函数。这需要引用动态数组,以及长度并分配内存并返回引用。

在C ++中,我正在思考

的内容
void* setlength(void* pp, int array_size, int pointer_size, int target_size, ....) {
      void * p;
      // Code to allocate memory here via malloc/new
      // something like:   p = reinterpret_cast<typeid(pp)>(p); 
      //                   p=(target_size) malloc(array_size);
      return p;
}

我的问题是:有没有办法将指针类型传递给这样的函数并成功分配内存(可能通过typeid参数?)?我可以使用

吗?
<reinterpret_cast>

不知?最终目标在于使用方面如下:

float*** p;
p=setlength(100,sizeof(float***),sizeof(float**),.....);

class B;
B** cp;
cp=setlength(100,sizeof(B**),sizeof(B*),.....);

任何帮助都是最受欢迎的。我知道我的建议代码是错的,但想传达一般的想法。感谢。

5 个答案:

答案 0 :(得分:5)

使用std :: vector而不是原始数组。 然后,您只需调用其resize()成员方法。

并使该函数成为处理任意类型的模板:

如果你想使用你的功能,它可能看起来像这样:

template <typename T>
std::vector<T>& setlength(std::vector<T>& v, int new_size) {
      v.resize(new_size);
      return v;
}

但是现在它很简单,你可能想要彻底消除这个功能,只需要开始调用resize

我不完全确定你在尝试用你的例子中的三重指针做什么,但看起来你不想调整大小,你想要初始化到一定的大小,这可能是使用vector构造函数完成:

std::vector<float>v(100);

答案 1 :(得分:2)

如果你想按字面意思做,你会这样做:

template <typename T>
T* SetLength(T* arr, size_t len) {
    return static_cast<T*>(realloc(arr, sizeof(T) * len));
}

请注意,数组必须已分配malloccalloc。另请注意,这实际上并没有调整内存大小 - 它会释放内存并重新分配适当大小的内存。如果传入的数组有任何其他指针,则之后它们将无效。

您最好使用更加惯用的C ++解决方案,例如std::vector

答案 2 :(得分:1)

对于多维数组,可能最好的选择是使用boost的multi_array库:

typedef boost::multi_array<float, 3> array_type;
array_type p(boost::extents[100][100][100]); // make an 100x100x100 array of floats
p[1][2][3] = 4.2;

这使您可以完全抽象出设置多维数组的分配和细节。此外,由于它使用线性存储,因此您可以轻松获得线性存储的效率优势。

如果做不到这一点,你还有其他三个主要选择。

不使用外部库的大多数C ++ -y选项是使用STL容器:

std::vector<float **> p;
p.resize(100);

multi_array一样,p会在超出范围时自动释放。您可以使用p.size()获取向量范围。然而,向量只会为你处理一个维度,所以你最终会做嵌套向量(ick!)。

您也可以直接使用new

float ***p = new float**[100];

要解除分配:

delete [] p;

这具有std::vector的所有缺点,而且它不会为您释放它,并且您无法在以后获得大小。

如果上述三种方法无法分配足够的内存,则会抛出std::bad_alloc类型的异常。

最后,为了完整性,有C路线,calloc()

float ***p = (float ***)calloc(100, sizeof(*p));

免费:

free((void*)p);

这来自C并且对所有演员都有点丑陋。对于C ++类,它也不会为您调用构造函数。此外,没有检查参数中的sizeof是否与演员表一致。

如果calloc()无法分配内存,它将返回NULL;你需要检查并处理它。

答案 3 :(得分:0)

新的运算符本身就是你所要求的,除了为了适当地分配双/三指针,你必须按照以下几行做一些事情:

float** data = new float*[size_of_dimension_1];
for ( size_t i=0 ; i<size_of_dimension_1 ; ++i )
    data[i] = new float[size_of_dimension_2];

...

// to delete:
for ( size_t i=0 ; i<size_of_dimension_1 ; ++i )
    delete [] data[i];
delete [] data;

编辑:我建议使用众多C ++数学/矩阵库中的一个。我建议uBlas

答案 4 :(得分:0)

以C ++方式执行此操作:

1)正如jalf所说,如果你能,可以选择std :: vector 2)不要做空* p。更喜欢将您的函数设为T类型的模板。