c ++:如何从函数接收可变长度输出数组

时间:2014-04-15 17:41:11

标签: c++ arrays matlab

我正在用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,但通常我不会知道,直到我跑。

3 个答案:

答案 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::vectorlink)可以用作具有连续内存块的容器,用于根据您的需要动态调整大小。您可以使用模板检索数组大小并将值分配给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::vectorIf 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);
...