Size of a structure

607 views (last 30 days)
Lisa Lee
Lisa Lee on 4 Aug 2017
Commented: Walter Roberson on 10 Dec 2023
After I looked at the Example1 below, I thought the size of a structure was the same as the size of the largest field. However, this concept was conflicted when I looked at the Example2. Can someone please help me to understand how the size of a structure is defined?
Exameple1:
field1 = 'f1'; value1 = zeros(1,10);
field2 = 'f2'; value2 = {'a', 'b'};
field3 = 'f3'; value3 = {pi, pi.^2};
field4 = 'f4'; value4 = {'fourth'};
s = struct(field1,value1,field2,value2,field3,value3,field4,value4)
size: 1×2
Example2:
load fisheriris % Fisher's iris data (1936)
% Create a structure of arrays
fisherIrisStructureOfArrays.species = species;
fisherIrisStructureOfArrays.specimenNumber = [1:150]';
fisherIrisStructureOfArrays.sepalLength = meas(:,1);
fisherIrisStructureOfArrays.sepalWidth = meas(:,2);
fisherIrisStructureOfArrays.petalLength = meas(:,3);
fisherIrisStructureOfArrays.petalWidth = meas(:,4);
Size: 1x1
  9 Comments
Adam
Adam on 4 Aug 2017
s1 = struct(field1,value1,field2,value2);
is a convenience function overload though really. It allows you to throw in loads of data to a non-scalar struct all at once rather than build it up in a more verbose manner.
Similarly to the way functions like imagesc take it upon themselves to flip the y axis and make other changes to axes properties rather than just do the raw action of putting your image data on an axes, this is a method that rolls up a potentially large amount of lines of code into one quick way of creating a struct.
These kind of function overloads often require some deeper understanding, in the same way that functions involving meshgrids and their ilk still confuse me.
When working with your own structs rather than arbitrary examples though it should be less confusing because you know what to expect of your structure so its size should not be a surprise and you would just create it in whichever way is best for you. That its class should always be 'struct' though cannot be argued. The size of the struct array it creates certainly may come as a surprise to people new to it (I very rarely use structs myself so I am not familiar with their creation syntax either other than the simple creation as in example 2).
Jan
Jan on 5 Aug 2017
@Christos: I see. You could expect struct(a, {1,2}) to reply a scalar struct. Instead of relying on intuition, I tend to trust the documentation. There I find, that I need a nested cell to create a scalar struct with a cell as value, because cells create a struct array.
I've written a function S = ScalarStruct as C-Mex, but found the benefits too marginal for a daily use or for publishing it in the FEX.

Sign in to comment.

Answers (2)

EB
EB on 3 Jun 2019
transform your structure to table:
size( struct2table(DATA), 2)

Jan
Jan on 4 Aug 2017
Edited: Jan on 4 Aug 2017
If you create a struct by the struct command, the size of the array is determined by the data, if they are provided as a cell array:
S = struct('A', {1, 2}, 'B', 0);
% Now S is a [1 x 2] struct array, because the data for A are given
% as {1 x 2} cell. This is equivalent to:
S(1).A = 1
S(1).B = 0
S(2).A = 2
S(2).B = 0
If you want S to be a scalar and contain the cell {1,2} as field A, use:
S = struct('A', {{1, 2}}, 'B', 0);
% Now S is a scalar struct, because the data for A are provided
% as {1 x 1} cell, which contains the cell {1,2}. This equivalent to:
S(1).A = {1,2}
S(1).B = 0
In the 2nd example, you define the fields of the scalar struct directly. The difference you see comes from the way the struct() command works. Note that this is explained clearly in the documentation:
doc struct
  7 Comments
Robert Scott
Robert Scott on 10 Dec 2023
thanks
Walter Roberson
Walter Roberson on 10 Dec 2023
There is also a different measure of "size" available.
If you use whos then you can see a field named Bytes that indicates the amount of memory required to store the contents of a variable.
That size excludes the amount of memory needed to describe the variable itself -- does not include the memory needed to store the name of the variable or the size of the variable or the class() of the variable or information such as whether the variable is complex-valued or is global.
For example
A = zeros(3,5,'uint8');
B = zeros(3,5,'double');
C = 'hello';
D = "hello";
whos A B C D
Name Size Bytes Class Attributes A 3x5 15 uint8 B 3x5 120 double C 1x5 10 char D 1x1 150 string
A is 3 by 5 uint8 and each uint8 takes 1 byte, so A is 3 * 5 * 1 = 15 bytes
B is 3 by 5 double and each double takes 8 bytes, so B is 3 * 5 * 8 = 120 bytes
C is 1 x 5 char and each char takes 2 bytes, so C is 1 x 5 x 2 = 10 bytes
D is considered a 1 x 1 string() array. The storage for string() arrays is... odd
  • empty string array has 96 bytes overhead
  • each additional array entry takes 52 bytes
  • those 52 bytes hold up to 10 characters (each 2 bytes per char)
  • then the size of the entry goes up by 10 bytes, which holds up to 5 char (2 bytes per char)
  • after that, the size of entries goes up in 16 byte increments, which holds up to 8 char (2 bytes per char)
I could more easily understand if the size consistently went up in 16 byte increments, each holding up to 8 chars, but the 10-chars then 5-chars initial bit has me scratching my head.
Anyhow, the point is that the Bytes field of whos() gives a measure of memory size (but not of array size in the sense that size() would return.)

Sign in to comment.

Categories

Find more on Structures in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!