Чтобы ограничить размер массива для массивов переменного размера, выполните одно из следующих действий:
Ограничение размера массива с помощью операторов assert
Если переменная, задающая размер массива, не является константой времени компиляции, используйте assert
оператор с реляционными операторами, чтобы ограничить переменную. Это помогает генератору кода определить максимальный размер для массива.
Следующие примеры ограничивают размер массива, используя assert
операторы:
Когда размер массива задан переменными Входами
Задайте array_init функции
который инициализирует массив y
с входной переменной N
:
function y = array_init (N) assert(N <= 25); % Generates exception if N > 25 y = zeros(1,N);
assert
оператор ограничивает входные N
до максимального размера 25. При отсутствии assert
оператор, y
назначается указатель на массив в сгенерированном коде, что позволяет динамически выделять память.
Когда размер массива получен из расчетов с использованием входных переменных
Задайте функцию, array_init_from_prod
, которая принимает две входные переменные, M
и N
, и использует их продукт, чтобы задать максимальный размер массива, y
.
function y = array_init_from_prod (M,N) size=M*N; assert(size <= 25); % Generates exception if size > 25 y=zeros(1,size);
assert
оператор ограничивает продукт M
и N
максимум до 25.
Также, если вы ограничиваете M
и N
индивидуально это приводит к динамическому выделению памяти:
function y = array_init_from_prod (M,N)
assert(M <= 5);
assert(N <= 5);
size=M*N;
y=zeros(1,size);
Этот код вызывает динамическое выделение памяти из-за M
и N
оба могут иметь неограниченные отрицательные значения. Поэтому их продукт может быть неограниченным и положительным, хотя по отдельности их положительные значения ограничены.
Совет
Поместите оператор assert в переменную непосредственно перед тем, как он будет использоваться для задания размера массива.
Совет
Вы можете использовать assert
операторы для ограничения размеров массивов в большинстве случаев. При расширении массива внутри цикла эта стратегия не работает, если количество запусков цикла известно только во время выполнения.
Ограничение конкатенаций в цикле Использование coder.varsize с верхними границами
Можно расширить массивы сверх их начального размера путем конкатенации. Когда вы конкатенируете дополнительные элементы внутри цикла, существует два синтаксических правила для расширения массивов.
Размер массива во время инициализации не является константой времени компиляции
Если размер массива во время инициализации не является константой времени компиляции, можно расширить его, сгруппировав дополнительные элементы:
function out=ExpandArray(in) % Expand an array by five elements out = zeros(1,in); for i=1:5 out = [out 0]; end
Размер массива во время инициализации является константой времени компиляции
Перед конкатенированием элементов необходимо объявить массив переменным размером с помощью coder.varsize
:
function out=ExpandArray() % Expand an array by five elements out = zeros(1,5); coder.varsize('out'); for i=1:5 out = [out 0]; end
Любой случай приводит к динамическому выделению памяти. Чтобы предотвратить динамическое выделение памяти в таких случаях, используйте coder.varsize
с явными верхними границами. В этом примере показано, как использовать coder.varsize
с явными верхними границами:
Задайте функцию, RunningAverage
, который вычисляет среднее течение N
-элемент подмножество массива:
function avg=RunningAverage(N) % Array whose elements are to be averaged NumArray=[1 6 8 2 5 3]; % Initialize average: % These will also be the first two elements of the function output avg=[0 0]; % Place a bound on the argument coder.varsize('avg',[1 8]); % Loop to calculate running average for i=1:N s=0; s=s+sum(NumArray(1:i)); avg=[avg s/i]; % Increase the size of avg as required by concatenation end
Выходные выходы, avg
, - массив, который можно развернуть по мере необходимости для соответствия средним текущим средним значениям. Когда вычисляется новое рабочее среднее значение, оно добавляется к массиву avg
посредством конкатенации, тем самым расширяя массив.
Потому что максимальное количество средних оборотов равно количеству элементов в NumArray
, можно задать явную верхнюю границу для avg
в coder.varsize
оператор. В этом примере верхняя граница равна 8 (два начальных элемента плюс шесть элементов NumArray
).
Сгенерируйте код для RunningAverage
с входным параметром типа double
:
codegen -config:lib -report RunningAverage -args 2
В сгенерированном коде avg
назначается массив размером 8 (статическое выделение памяти). Определение функции для RunningAverage
появляется следующим образом (с использованием встроенных типов C):
void RunningAverage (double N, double avg_data[8], int avg_size[2])
Напротив, если вы удаляете явную верхнюю границу, сгенерированный код динамически распределяет avg
.
Замените оператор
coder.varsize('avg',[1 8]);
с:
coder.varsize('avg');
Сгенерируйте код для RunningAverage
с входным параметром типа double
:
codegen -config:lib -report RunningAverage -args 2
В сгенерированном коде avg
назначается указатель на массив, что позволяет динамически выделять память. Определение функции для RunningAverage
появляется следующим образом (с использованием встроенных типов C):
void Test(double N, emxArray_real_T *avg)
Примечание
Динамическое выделение памяти также происходит, если вы предшествуете coder.varsize('avg')
с помощью следующего оператора assert:
assert(N < 6);
assert
оператор не ограничивает количество конкатенаций в цикле.Ограничение размера массива при переставке матрицы
Оператор out = reshape(in,m,n,...)
принимает массив, in
, как аргумент и возвращает массив, out
, имеющих те же элементы, что и in
, но изменился как m
-by- n
-by- ...
матрица. Если одна из переменных size m,n,...
. не является константой времени компиляции, затем динамическим выделением памяти out
происходит.
Чтобы избежать динамического выделения памяти, используйте assert
оператор перед операцией reshape
оператор, чтобы ограничить переменные size m,n,...
на numel(in)
. В этом примере показано, как использовать assert
оператор перед reshape
оператор:
Задайте функцию, ReshapeMatrix
, которая принимает переменный вход, N
, и изменяет форму матрицы, mat
, иметь N
строки:
function [out1,out2] = ReshapeMatrix(N) mat = [1 2 3 4 5; 4 5 6 7 8] % Since mat has 10 elements, N must be a factor of 10 % to pass as argument to reshape out1 = reshape(mat,N,[]); % N is not restricted assert(N < numel(mat)); % N is restricted to number of elements in mat out2 = reshape(mat,N,[]);
Сгенерируйте код для ReshapeArray
использование codegen
команда (входной параметр не должна быть коэффициентом 10):
codegen -config:lib -report ReshapeArray -args 3
Пока out1
динамически выделяется, out2
назначается массив с размером 100 (= 10 X 10) в сгенерированном коде.
Совет
Если ваша система имеет ограниченную память, не используйте assert
оператор таким образом. Для n
-элементная матрица, assert
оператор создает n
-by- n
матрица, которая может быть большой.
1. Если смысл перевода понятен, то лучше оставьте как есть и не придирайтесь к словам, синонимам и тому подобному. О вкусах не спорим.
2. Не дополняйте перевод комментариями “от себя”. В исправлении не должно появляться дополнительных смыслов и комментариев, отсутствующих в оригинале. Такие правки не получится интегрировать в алгоритме автоматического перевода.
3. Сохраняйте структуру оригинального текста - например, не разбивайте одно предложение на два.
4. Не имеет смысла однотипное исправление перевода какого-то термина во всех предложениях. Исправляйте только в одном месте. Когда Вашу правку одобрят, это исправление будет алгоритмически распространено и на другие части документации.
5. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.