Чтобы ограничить размер массивов для массивов переменного размера, выполнить одно из следующих действий:
Ограничьте Размер Массивов Используя операторы контроля
Если переменный размер определения массивов не является постоянным временем компиляции, используйте 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
- n
- ...
матрица. Если одна из переменных m,n,...
размера. не постоянное время компиляции, затем динамическое выделение памяти
out
происходит.
Чтобы избежать динамического выделения памяти, используйте assert
оператор перед reshape
оператор, чтобы ограничить переменные m,n,...
размера к
numel(in)
. В этом примере показано, как использовать assert
оператор прежде a 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
- n
матрица, которая может быть большой.
1. Если смысл перевода понятен, то лучше оставьте как есть и не придирайтесь к словам, синонимам и тому подобному. О вкусах не спорим.
2. Не дополняйте перевод комментариями “от себя”. В исправлении не должно появляться дополнительных смыслов и комментариев, отсутствующих в оригинале. Такие правки не получится интегрировать в алгоритме автоматического перевода.
3. Сохраняйте структуру оригинального текста - например, не разбивайте одно предложение на два.
4. Не имеет смысла однотипное исправление перевода какого-то термина во всех предложениях. Исправляйте только в одном месте. Когда Вашу правку одобрят, это исправление будет алгоритмически распространено и на другие части документации.
5. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.