Main Content

Use Dynamic Memory Allocation for Unbounded Variable-Size Signals in C++ Code Generation

This example shows how to generate C++ code that uses dynamic memory allocation for unbounded variable-size signals. Unbounded variable-size signals are variable-size signals that have no finite upper bounds for at least one of the signal dimensions. Therefore, these signals can transmit data with any dimension size. Allocating memory for these signals dynamically on the heap as needed at run time is beneficial when:

  • You do not have a mechanism to know the upper bounds of the signal dimensions.

  • The estimated upper bound might be a deficit or surplus to the actual upper bound. Overestimating an upper bound results in a portion of the allocated memory going unused and underestimating the upper bound can cause stack overflow.

However, allocating memory dynamically and freeing that memory at run-time can increase the code execution time.

Example Model

This example uses the model CppDynMemAlloc.

The model includes MATLAB code in the MATLAB Function block MFB. The code in MFB takes and produces variable-size signals as input and output. Consider, you do not know the accurate upper bounds of the second dimension of the input and output signals. Therefore, you specify the signals as unbounded by setting the second dimension of the signals to Inf as follows:

  • The Inport block In passes the input signal to MBF. To create an unbounded variable-size signal whose second dimension is unbounded, the second dimension of the Port dimensions parameter is set to Inf and the Variable-size signal parameter is set to Yes in the Block Parameters dialog box.

  • On the Modeling tab, click Model Explorer and select the output port of MFB. The second dimension of the Size parameter for the output port is set to Inf. The Support variable-size arrays parameter for the block and the Variable size parameter for the relevant port are selected.

Configure Model for Dynamic Memory Allocation

To use dynamic memory allocation for unbounded variable-size signals, open the Configuration Parameters dialog box and configure the model as follows:

1. On the Solver pane, set Solver to discrete (no continuous states).

2. On the Data Import/Export pane, set Format to Dataset.

3. On the Code Generation pane, set Language to C++.

4. On the Simulation Target pane, select Dynamic memory allocation in MATLAB functions.

Generate C++ Code

After you configure the model to use dynamic memory allocation, generate code.

1. To create a code generation report and open it automatically, in the Configuration Parameters dialog box, on the Report pane, select:

  • Create code generation report

  • Open report automatically

2. To generate code, open the Simulink Coder app and click Build. Alternatively, click Ctrl+B.

### Starting build procedure for: CppDynMemAlloc
### Successful completion of build procedure for: CppDynMemAlloc

Build Summary

Top model targets:

Model           Build Reason                                         Status                        Build Duration
=================================================================================================================
CppDynMemAlloc  Information cache folder or artifacts were missing.  Code generated and compiled.  0h 0m 11.841s 

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 13.051s

Inspect C++ Code

1. Because the model uses the grt.tlc system target file, the code generator defines dynamic arrays for the unbounded variable-size signals as instances of the class template coder::array. To view the dynamic arrays, open the CppDynMemAlloc.h file.

/* External outputs (root outports fed by signals with default storage) */
struct ExtY_CppDynMemAlloc_T {
  coder::array<real_T,2> out1;         /* '<Root>/out1' */
  coder::array<real_T,2> Out2;         /* '<Root>/Out2' */
};

2. To view the implementation of the class template, open the header file coder_array.h generated in the build folder. The top of the header file contains details about the coder::array class interface.

3. In coder_array.h, the code generator also implements the set_size method in the coder namespace. The method uses the CODER_ALLOC and CODER_DEALLOC macros through ensureCapacity() to perform memory allocation and freeing dynamically for dynamic arrays.

      void set_size(Dims... dims)
    {
      coder::detail::match_dimensions<N == sizeof...(dims)>::check();
      set_size_i<0>(dims...);
      ensureCapacity(numel());

4. To view the use of set_size method, open the CppDynMemAlloc.cpp file. The code calls the set_size method to allocate and free memory dynamically for the defined dynamic arrays at run time.

  /* MATLAB Function: '<Root>/MFB' incorporates:
   *  Inport: '<Root>/In'
   *  Outport: '<Root>/out1'
   */
  CppDynMemAlloc_Y.out1.set_size(CppDynMemAlloc_U.In.size(0),
    CppDynMemAlloc_U.In.size(1));
  loop_ub = CppDynMemAlloc_U.In.size(1);
  for (i_0 = 0; i_0 < loop_ub; i_0++) {
    loop_ub_0 = CppDynMemAlloc_U.In.size(0);
    for (i = 0; i < loop_ub_0; i++) {
      CppDynMemAlloc_Y.out1[i + CppDynMemAlloc_Y.out1.size(0) * i_0] =
        CppDynMemAlloc_U.In[CppDynMemAlloc_U.In.size(0) * i_0 + i] * 5.0;
    }
  }

Related Topics