У меня есть следующий файл .m (с именем testmemoryallocation.m
), предназначенный для генерации кода в Matlab Coder. Конечно, это всего лишь тестовый файл, демонстрирующий концепцию.
function output = testmemoryallocation(dim) %#codegen
%TESTMEMORYALLOCATION Tests allocation of large 3D arrays
output = coder.nullcopy(zeros([dim, dim, dim]));
output(:) = 5;
end
Я строю это, используя следующий скрипт сборки (настройки по умолчанию из приложения Coder)
%% Create configuration object of class 'coder.CodeConfig'.
cfg = coder.config('lib','ecoder',false);
cfg.GenerateReport = true;
cfg.GenCodeOnly = true;
cfg.HardwareImplementation = coder.HardwareImplementation;
cfg.HardwareImplementation.ProdIntDivRoundTo = 'Undefined';
cfg.HardwareImplementation.TargetIntDivRoundTo = 'Undefined';
%% Define argument types for entry-point 'testmemoryallocation'.
ARGS = cell(1,1);
ARGS{1} = cell(1,1);
ARGS{1}{1} = coder.typeof(0);
%% Invoke MATLAB Coder.
codegen -config cfg testmemoryallocation -args ARGS{1}
Результирующий сгенерированный код C из этого процесса сборки выглядит следующим образом:
/*
* testmemoryallocation.c
*
* Code generation for function 'testmemoryallocation'
*
*/
/* Include files */
#include "rt_nonfinite.h"
#include "testmemoryallocation.h"
#include "testmemoryallocation_emxutil.h"
/* Function Definitions */
void testmemoryallocation(double dim, emxArray_real_T *output)
{
int i0;
int loop_ub;
/* TESTMEMORYALLOCATION Tests allocation of large 3D arrays */
i0 = output->size[0] * output->size[1] * output->size[2];
output->size[0] = (int)dim;
emxEnsureCapacity((emxArray__common *)output, i0, (int)sizeof(double));
i0 = output->size[0] * output->size[1] * output->size[2];
output->size[1] = (int)dim;
emxEnsureCapacity((emxArray__common *)output, i0, (int)sizeof(double));
i0 = output->size[0] * output->size[1] * output->size[2];
output->size[2] = (int)dim;
emxEnsureCapacity((emxArray__common *)output, i0, (int)sizeof(double));
loop_ub = (int)dim * (int)dim * (int)dim;
for (i0 = 0; i0 < loop_ub; i0++) {
output->data[i0] = 5.0;
}
}
/* End of code generation (testmemoryallocation.c) */
Вопрос в следующем: есть ли способ в MATLAB Coder (в файле testmemoryallocation.m
) проверить, что память действительно выделена? Выделение памяти происходит в функции emxEnsureCapacity, которая сама по себе не возвращает информацию об успешном выделении (насколько я могу судить). Я хотел бы иметь возможность изящно выйти из вызывающей функции, если системной памяти недостаточно чтобы завершить процесс. Например, я хотел бы добавить вывод result
в testmemoryallocation, который указывал бы, произошла ли ошибка при выделении памяти. Есть ли способ сделать это?
На самом деле вопрос сводится к следующему: есть ли способ получить доступ к emxArrays, чтобы проверить, что поле data
структуры не равно нулю. Возможно, файл .c называется coder.ceval? Есть ли способ указать coder.ceval передавать тип emxArray вместо базовых типов (double или int), чтобы можно было написать базовый код .c для взаимодействия со структурой?
РЕДАКТИРОВАТЬ: отличный принятый ответ касается как этого вопроса, так и основной ошибки в (2015a) Coder в сгенерированном коде c. В файле _emxutil функция emxEnsureCapacity имеет возможный бесконечный цикл, если запрошенное количество элементов превышает intmax/2
.