Чтобы ограничить размер массивов для массивов переменного размера, выполнить одно из следующих действий:
Ограничьте Размер Массивов Используя операторы контроля
Если переменный размер определения массивов не является постоянным временем компиляции, используйте оператор 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
, чтобы ограничить размеры массивов в большинстве случаев. При расширении массива в цикле не работает эта стратегия, если количество выполнений цикла известно только во время выполнения.
Ограничьте Конкатенации в Цикле Используя 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(N < 6);
assert
не ограничивает количество конкатенаций в цикле.Ограничьте размер массивов при реконструкции матрицы
Оператор out = reshape(in,m,n,...)
берет массив, in
, в качестве аргумента и возвращает массив, out
, имея те же элементы как in
, но измененный как m
-by-n-by-
...
матрица. Если одна из переменных размера m,n,...
. не постоянное время компиляции, затем динамическое выделение памяти out
происходит.
Чтобы избежать динамического выделения памяти, используйте оператор assert
перед оператором reshape
, чтобы ограничить переменные размера 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. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.