主要内容

生成的代码中数组的表示

代码生成器会生成 C/C++ 数组定义,这些定义取决于数组元素类型以及数组使用的是静态还是动态内存分配。使用生成的数组实现将您的数组与生成的代码对接起来。

数组的内存分配需要不同实现:

  • 对于其大小限制在预定义内存阈值内的固定大小数组或可变大小数组,生成的 C/C++ 定义包含一个由元素组成的固定大小数组和一个存储数组元素总数的大小向量。在某些情况下,固定大小的元素数组和大小向量存储在一个结构体中。此数组的内存来自程序堆栈,并且是静态分配的。

  • 对于在编译时其大小无界的数组,或其边界超出预定义阈值的数组,生成的 C 定义包含一个名为 emxArray 的数据结构体。生成的 C++ 定义包含一个 coder::array 类模板。

预定义的阈值大小(以字节为单位)在您的配置对象中指定。该参数的默认值为 65536。请参阅 coder.MexCodeConfigcoder.CodeConfigcoder.EmbeddedCodeConfig 中的 DynamicMemoryAllocationThreshold

对于动态分配的数组,运行时分配的大小是基于当前数组大小设置的。在程序执行期间,当超出运行时分配的大小时,生成的代码会从堆中重新分配额外的内存空间,并将其添加到动态数组存储中。

下表列出了在生成的代码中数组表示的一些典型情况。

算法说明和数组大小

MATLAB® 函数

生成的 C/C++ 代码

创建一个固定大小的 1×500 行向量。该数组是 MATLAB 函数的输出

生成的代码将内存分配给程序堆栈上的一个固定大小向量。

function B = create_vec0 %#codegen
B = zeros(1,500);
end
void create_vec0(double B[500])
{
  memset(&B[0], 0, 500U * sizeof(double));
}

该数组在生成的代码中是函数的输入。

创建一个固定大小的 1×20 行向量。将数组声明为可变大小,边界为 500 个元素。将此可变大小数组赋给输入数组。

此数组的边界为大小阈值,而且该数组在生成的代码中是函数的输入。

function create_vec1(B) %#codegen
A = zeros(1,20);
coder.varsize('A',[1 500],[0 1]);
B = A;
end
void create_vec1(double B_data[], int B_size[2])
{
  int i;
  B_size[0] = 1;
  B_size[1] = 20;
  for (i = 0; i < 20; i++) {
    B_data[i] = 1.0;
  }
}

注意

生成的代码包括函数参数中的输入。

创建一个本地固定大小的 1×20000 行向量。将数组声明为可变大小,边界为 30,000 个元素。

可变大小数组超出预定义的动态内存分配阈值。此数组存储在堆内存上。

生成的代码包含函数参数中的输出数组。

function B = create_vec2() %#codegen
A = ones(1,20000);
coder.varsize("A",[1 30000], [0 1]);
B = [1 A];
end

C:

void create_vec2(emxArray_real_T *B)
{
  double *B_data;
  int i;
  i = B->size[0] * B->size[1];
  B->size[0] = 1;
  B->size[1] = 20001;
  emxEnsureCapacity_real_T(B, i);
  B_data = B->data;
  B_data[0] = 1.0;
  for (i = 0; i < 20000; i++) {
    B_data[i + 1] = 1.0;
  }
}

C++:

void create_vec2(coder::array<double, 2U> &B)
{
  B.set_size(1, 20001);
  B[0] = 1.0;
  for (int i{0}; i < 20000; i++) {
    B[i + 1] = 1.0;
  }
}

创建一个数组,其大小由无界整数输入确定。

生成的数组大小未知,并且在编译时无界。

function y = create_vec3(n) %#codegen
y = ones(1,n,'int8');

C:

void create_vec3(double n, emxArray_int8_T *y)
{
  int i;
  int loop_ub_tmp;
  signed char *y_data;
  i = y->size[0] * y->size[1];
  y->size[0] = 1;
  loop_ub_tmp = (int)n;
  y->size[1] = (int)n;
  emxEnsureCapacity_int8_T(y, i);
  y_data = y->data;
  for (i = 0; i < loop_ub_tmp; i++) {
    y_data[i] = 1;
  }
}

C++:

void create_vec3(double n, coder::array<signed char, 2U> &y)
{
  int loop_ub_tmp;
  loop_ub_tmp = static_cast<int>(n);
  y.set_size(1, loop_ub_tmp);
  for (int i{0}; i < loop_ub_tmp; i++) {
    y[i] = 1;
  }
}

要了解 emxArray 数据结构体的信息,请参阅在生成的函数接口中使用动态分配的 C 数组

要了解 coder::array 类模板的信息,请参阅Use Dynamically Allocated C++ Arrays in Generated Function Interfaces

自定义接口生成

默认情况下,生成的 C++ 代码使用 coder::array 模板来实现动态分配的数组。您可以选择生成使用 C 样式 emxArray 数据结构体的 C++ 代码来实现动态分配数组。要生成 C 样式 emxArray 数据结构体,请执行以下操作之一:

要在生成的代码中为可变大小数组创建动态分配的数组,请执行以下操作之一:

  • 在代码配置对象中,将 EnableDynamicMemoryAllocation 属性设置为 true

  • 在“代码生成设置”对话框中,选中启用动态内存分配复选框。

默认情况下,限制在阈值大小内的数组不会在生成的代码中使用动态分配。您也可以禁用动态内存分配和更改动态内存分配阈值。请参阅控件可变大小数组的内存分配

另请参阅

| | |

主题