I had created a structure made so:
head.number = 3;
head.pck_rcv = [1 0 0];
heads(2).number = 5;
head(2).pck_rcv = [1 1 0];
and so on.
How can I preallocate a structure?

 채택된 답변

Jan
Jan 2012년 9월 22일
편집: Jan 2017년 10월 2일

27 개 추천

for k = n:-1:1 % Backwards!
head(k).number = 3;
head(k).pck_rcv = [1 0 0];
end
Now the final size of the struct array is created in the first iteration.
[EDITED] Alternatively:
head = struct('number', cell(1, 10), 'pck_rv', cell(1, 10));
Now head is a [1 x 10] struct array withe the fields 'number' and 'pck_rv'. Pre-allocating the contents of the fields is another job and you need a loop to do this. But now it can run in forward direction also.

댓글 수: 5

Jason
Jason 2012년 12월 13일
Jan, can you clarify something for me? On an earlier question, http://www.mathworks.com/matlabcentral/answers/30764#answer_39237 you gave the same suggestion. Oleg showed a test case where preallocating a struct by initializing the last element didn't appear to result in sufficient memory being allocated. Which is correct?
Jan
Jan 2012년 12월 13일
편집: Jan 2012년 12월 13일
@Jason: I've added a comment to Oleg's message now. There are two jobs to to when pre-allocating a struct array: 1. allocate the struct array itself, 2. allocate memory for all different fields. While point 1 can be solved in one step using either the struct('field', {data}) or the implicit pre-allocation by assigning the last element at first, the allocation of the contents of the fields cannot be done in one step. There is no way to pre-allocate n arrays simultaneously. Trying to do this results in "shared data copies", which means that all the fields share the same data value. At first this is fast and memory efficient. But when you change the values, an addition deep copy is performed for each element, which consumes more time than allocating the different arrays of the fields in a loop. For this reasons it is e.g. useless to "pre-allocate" the elements of a cell array, while pre-allocating the cell itself is strongly recommended:
n = 1e5;
tic; for k = 1:1000
clear('c');
for in = 1:n
c{in} = 'qvw';
end
end, toc
tic; for k = 1:1000
clear('c');
c = cell(1, n); % important pre-allocation of cell
c(:) = {'asd'}; % Useless pre-allocation of cell elements
% Now all elements of C point to the same memory such that
% the characters 'asd' are found once only in the RAM.
for in = 1:n
c{in} = 'qvw'; % Now "unsharing" the string consumes time
end
end, toc
tic; for k = 1:1000
clear('c');
c = cell(1, n); % important pre-allocation of cell
for in = 1:n
c{in} = 'qvw';
end
end, toc
This is very similar for structs, because the only difference to cells is the storage of the fieldnames in a CHAR array, while the organization of the elements is equal (therefore struct2cell and cell2struct are so fast).
Summary: Pre-allocate the struct in one step, pre-allocate the fields separately for each element of the struct in a loop, or assign them directly if possible.
alternatively syntax worked . Thanks
thanks! that
head = struct('number', cell(1, 10), 'pck_rv', cell(1, 10));
work fine!
I am accepting Jan's answer as it provides a robust solution to the question posted.

댓글을 달려면 로그인하십시오.

추가 답변 (2개)

Azzi Abdelmalek
Azzi Abdelmalek 2012년 9월 22일
편집: Azzi Abdelmalek 2012년 9월 22일

5 개 추천

heads=struct('numbers',zeros(10,1), 'pck_rcv',zeros(10,3))
%then
for k=1:n
heads.numbers(k)=2
heads.pck_rcv(k,:)=[1 2 3]
end

댓글 수: 3

This should be the top answer IMO :)
Jan
Jan 2017년 10월 2일
@Alexandra: I do not agree. Salvatore asked for a struct array: "head(2).numbers and so on". Azzi's suggestion creates a scalar struct only.
True, I just tried it out and realised it wasn't what I wanted either! Thanks for the response.

댓글을 달려면 로그인하십시오.

Walter Roberson
Walter Roberson 2012년 12월 13일

2 개 추천

head = struct('number', {3, 5}, 'pck_rcv', {[1 0 0], [1 0 1]})

카테고리

도움말 센터File Exchange에서 Variables에 대해 자세히 알아보기

태그

질문:

2012년 9월 22일

댓글:

2024년 3월 27일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by