[英]c++: How to receive variable length output array from a function
I am writing a wrapper in C++ which calls another C++ function. 我正在用C ++写一个包装程序,该包装程序调用了另一个C ++函数。 But the output of that function is a variable length array.
但是该函数的输出是可变长度数组。 Unfortunately, array size needs to be compile time constant.
不幸的是,数组大小需要是编译时间常数。
Current what I have: 目前我所拥有的:
double output[5];
mycustomfunction(input1,input2,input3,output);
for(unsigned i=0;i<(sizeof(output)/sizeof(double));i++)
cout << ',' << output[i];
But I don't know how much will be the size of output until I run the function. 但是在运行函数之前,我不知道输出的大小是多少。 I need to make the output declaration as dynamic.
我需要使输出声明为动态。
Note: I cannot adjust mycustomfunction as it is machine generated code by Matlab coder. 注意:我无法调整mycustomfunction,因为它是Matlab编码器由机器生成的代码。 So it has to be an array.
因此它必须是一个数组。
Edit: I gave [5] in this example for a test case where I know the output is 5, but generally I wouldn't know until I run. 编辑:在这个例子中,我给出了一个[5]的测试用例,我知道输出是5,但是通常直到运行我才知道。
The Pure C++ Solution: using std::vector
纯C ++解决方案:使用
std::vector
In C++, for dynamic arrays, you should use std::vector
. 在C ++中,对于动态数组,应使用
std::vector
。 Its size can be dynamically changed (eg using std::vector::resize()
, or adding elements using std::vector::push_back()
, etc.), and std::vector
knows its own size (eg calling std::vector::size()
). 它的大小可以动态更改(例如,使用
std::vector::resize()
或使用std::vector::push_back()
等添加元素),并且std::vector
知道其自身的大小(例如调用std::vector::size()
)。
std::vector<double> DoSomething(...);
(Note that thanks to C++11 move semantics, even returning a very big vector is efficient.) (请注意,由于使用了C ++ 11 move语义,即使返回很大的向量也是有效的。)
The solution with C-isms C-isms解决方案
If you can't use STL classes, an alternative is to use raw C pointers, and specify a size parameter (since raw C pointers don't know the size of the array pointed to). 如果您不能使用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);
Still another option is to allocate the array inside the function, and return it as the return value: 还有一个选择是在函数内部分配数组,并将其作为返回值返回:
double* DoSomething( ..., int* resultSize);
or use a double-pointer in the parameter list: 或在参数列表中使用双指针:
// Output array allocated by the function.
// The caller must free it.
void DoSomething( ..., double** output, int * resultSize);
Anyway, the std::vector
solution is the best "pure C++" solution. 无论如何,
std::vector
解决方案是最好的“纯C ++”解决方案。 The others are kind of "C-isms" . 其他的则是种“ C主义” 。
In C++ std::vector
( link ) can be used as a container with contiguous memory chunk for data resized dynamically according to your needs. 在C ++中,
std::vector
( link )可以用作具有连续内存块的容器,用于根据需要动态调整数据大小。 You can use a template to retrieve array size and assign values to a vector
: 您可以使用模板来检索数组大小并将值分配给
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);
}
usage: 用法:
std::vector<double> vd;
double output[5];
//... initialize output
copy_from_array( vd, output);
As others have said, the C++ way to create a variable length array is with a std::vector
. 正如其他人所说,创建可变长度数组的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 : 如果在调用
mycustomfunction
之前知道所需的数组大小,甚至可以将std::vector
作为数组传递 :
std::vector<double> arry;
arry.resize(5);
...
mycustomfunction(input1, input2, input3, &arry[0]);
However, if mycustomfunction
expects to realloc
the pointer passed into it, this will die. 但是,如果
mycustomfunction
希望realloc
传递给它的指针,这会死。 Or, worse, it won't die and will instead cause you heartache some other way . 或者,更糟糕的是,它不会死,而是会以其他方式引起您的心痛 。
Otherwise, we'll need additional details about how mycustomfunction
creates a variable length array, and how it reports the size to you. 否则,我们将需要有关
mycustomfunction
如何创建可变长度数组以及如何向您报告大小的其他详细信息。
There are C-style ways to deal with this, but they generally rely on the assumption that mycustomfunction
will malloc
the memory internally, and you will free
it ( or that you will call some custom function to release the memory ). 有C风格的方式来解决这个问题,但他们通常依赖于这一假设
mycustomfunction
将malloc
内部记忆,你会free
它( 或者你将调用一些自定义的函数来释放内存 )。 Even then, mycustomfunction
needs to either report the number of elements it created, or provide you some other way to find out how many elements it will create. 即使这样,
mycustomfunction
需要报告其创建的元素数量,或者提供其他方法来查找将创建的元素数量。 Broadly speaking, you have three common approaches: 广义上讲,您有三种常用方法:
mycustomfunction
allocates memory for you, and tells you how much it allocated mycustomfunction
为您分配内存,并告诉您分配了多少内存 size_t num_elements;
double* arry = mycustomfunction(input1, input2, input3, &num_elements);
for (size_t i = 0; i < num_elements; ++i) {
...
}
free(arry);
I would discourage this because it's very easy to forget to call free
in some code path. 我不建议这样做,因为很容易忘记在某些代码路径中进行
free
调用。
mycustomfunction
allocates memory for you, and you have to find a special marker (eg, not-a-number ) to know how much it allocated mycustomfunction
为您分配内存,并且您必须找到一个特殊的标记(例如not-a-number )才能知道分配了多少内存 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);
This has the same problem that it's easy to leak arry
. 这具有容易泄漏
arry
。 You also need to find a good value for your sentinel. 您还需要为您的哨兵找到一个好的价值。 Not-a-number (or 0, or
std::numeric_limits<double>::max()
, etc.) may well be a valid output. 非数字(或0,或
std::numeric_limits<double>::max()
等)可能是有效的输出。
mycustomfunction
, and either have a way to know how much memory you need, or a way to tell mycustomfunction
to not use more memory than you allocated mycustomfunction
之前分配内存,并且有一种方法可以知道所需的内存数量,或者可以告诉mycustomfunction
不要使用比分配的内存更多的内存 This is the approach I would recommend. 这是我推荐的方法。 And it allows you to use a
std::vector<double>
: 它允许您使用
std::vector<double>
:
std::vector<double> arry;
arry.resize(how_many_will_i_need(input1, input2, input3));
mycustomfunction(input1, input2, input3, &arry[0]);
...
Or: 要么:
std::vector<double> arry;
arry.resize(HOW_MANY_I_WANT);
mycustomfunction(input1, input2, input3, &arry[0], HOW_MANY_I_WANT);
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.