我正在用C ++编写一个包装器,它调用另一个C ++函数。但该函数的输出是一个可变长度数组。不幸的是,数组大小需要编译时间常数。
目前的情况:
double output[5];
mycustomfunction(input1,input2,input3,output);
for(unsigned i=0;i<(sizeof(output)/sizeof(double));i++)
cout << ',' << output[i];
但在运行该功能之前,我不知道输出的大小。我需要将输出声明变为动态。
注意:我无法调整mycustomfunction,因为它是由Matlab编码器生成的机器代码。所以它必须是一个数组。
编辑: 我在这个例子中给了[5]一个测试用例,我知道输出是5,但通常我不会知道,直到我跑。
答案 0 :(得分:2)
纯C ++解决方案:使用std::vector
在C ++中,对于动态数组,您应该使用 std::vector
。它的大小可以动态更改(例如使用std::vector::resize()
,或使用std::vector::push_back()
添加元素等),std::vector
知道自己的大小(例如调用std::vector::size()
)。< / p>
std::vector<double> DoSomething(...);
(注意,由于C ++ 11移动语义,即使返回一个非常大的向量也是有效的。)
使用C-isms的解决方案
如果你不能使用STL类,另一种方法是使用原始C指针,并指定一个size参数(因为原始C指针不知道指向的数组的大小)。
// The caller passes a pointer to the allocated output array, with specified size.
// The function fills the array with the result.
void DoSomething(/* some inputs ...*/, double* output, int outputSize);
还有一个选择是在函数内部分配数组,并将其作为返回值返回:
double* DoSomething( ..., int* resultSize);
或在参数列表中使用双指针:
// Output array allocated by the function.
// The caller must free it.
void DoSomething( ..., double** output, int * resultSize);
无论如何,std::vector
解决方案是最好的“纯C ++”解决方案。其他人都是“C-isms”。
答案 1 :(得分:0)
在C ++中std::vector
(link)可以用作具有连续内存块的容器,用于根据您的需要动态调整大小。您可以使用模板检索数组大小并将值分配给vector
:
template<typename T, size_t N>
void copy_from_array(vector<T> &target_vector, const T (&source_array)[N]) {
target_vector.assign(source_array, source_array+N);
}
用法:
std::vector<double> vd;
double output[5];
//... initialize output
copy_from_array( vd, output);
答案 2 :(得分:0)
正如其他人所说,创建可变长度数组的C ++方法是std::vector
。 If you know the size of the array you need before you call mycustomfunction
, you can even pass a std::vector
as an array:
std::vector<double> arry;
arry.resize(5);
...
mycustomfunction(input1, input2, input3, &arry[0]);
但是,如果mycustomfunction
期望realloc
指针传入其中,那么这将会死亡。或者更糟糕的是,它不会死亡,而是cause you heartache some other way。
否则,我们需要有关mycustomfunction
如何创建可变长度数组的其他详细信息,以及它如何向您报告大小。
有一种C风格的方法可以解决这个问题,但是它们通常依赖于假设mycustomfunction
会在内部malloc
内存,而你会free
它({{3} }})。即使这样,mycustomfunction
也需要报告它创建的元素数量,或者为您提供一些其他方法来确定它将创建多少元素。从广义上讲,您有三种常见的方法:
mycustomfunction
为您分配内存,并告诉您分配了多少内存size_t num_elements;
double* arry = mycustomfunction(input1, input2, input3, &num_elements);
for (size_t i = 0; i < num_elements; ++i) {
...
}
free(arry);
我会劝阻这个,因为忘记在某些代码路径中调用free
很容易。
mycustomfunction
为您分配内存,您必须找到一个特殊标记(例如,or that you will call some custom function to release the memory)才能知道它分配了多少double* arry = mycustomfunction(input1, input2, input3);
for (size_t i = 0; ; ++i) {
double d = arry[i];
if (d != d) { // only true for not-a-number
break;
}
...
}
free(arry);
这个问题很容易泄漏arry
。你还需要为你的哨兵找到一个好的价值。非数字(或0或std::numeric_limits<double>::max()
等)可能是有效的输出。
mycustomfunction
之前分配内存,并且要么知道需要多少内存,要么告诉mycustomfunction
不要使用比分配的内存更多的内存这是我推荐的方法。它允许您使用std::vector<double>
:
std::vector<double> arry;
arry.resize(how_many_will_i_need(input1, input2, input3));
mycustomfunction(input1, input2, input3, &arry[0]);
...
或者:
std::vector<double> arry;
arry.resize(HOW_MANY_I_WANT);
mycustomfunction(input1, input2, input3, &arry[0], HOW_MANY_I_WANT);
...