我正在做一个将一些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*),.....);
任何帮助都是最受欢迎的。我知道我的建议代码是错的,但想传达一般的想法。感谢。
答案 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));
}
请注意,数组必须已分配malloc
或calloc
。另请注意,这实际上并没有调整内存大小 - 它会释放内存并重新分配适当大小的内存。如果传入的数组有任何其他指针,则之后它们将无效。
您最好使用更加惯用的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类型的模板。