You mentioned your goal was to work with several structure of the same type, therefore you should be aware of the main two approaches available to you and how they compare:
1) array of structures
You can initialize it by growing the array dynamically
p(1).str = 'white';
p(1).r = 1;
p(1).g = 1;
p(1).b = 1;
p(2).str = 'black';
p(2).r = 0;
p(2).g = 0;
p(2).b = 0;
However its always better to start by pre-allocating the array
p = repmat( struct('r',[], 'g',[], 'b',[], 'str',[]), 1, 10);
another trick to pre-allocate:
p(10) = struct('r',[], 'g',[], 'b',[], 'str',[]);
Or even give all values at initialization:
p = struct('r',{1 0}, 'g',{1 0}, 'b',{1 0}, 'str',{'white' 'black'});
A simple way to fill values
names = {'white' 'black'};
[p(1:2).str] = names{:};
red = num2cell([1 0]);
[p(1:2).r] = red{:};
Here's how you retrieve all values of one field:
red = [p(:).r];
names = {p(:).str};
2) structures of arrays
p.r = [1 0];
p.g = [1 0];
p.b = [1 0];
p.str = {'white' 'black'};
p1 = [p.r(1) p.g(1) p.b(1)];
The advantage of this is that the structure is simply an array of pointer (r,g,b,str are stored separately in memory). Compare this to the previous approach, where we have an array of structure, and each structure has pointers to its field (there's quite a memory overhead):
>> s1 = repmat( struct('r',0, 'g',0, 'b',0), 1, 1000);
>> s2 = struct('r',zeros(1,1000), 'g',zeros(1,1000), 'b',zeros(1,1000));
>> whos
Name Size Bytes Class Attributes
s1 1x1000 204192 struct
s2 1x1 24372 struct
On the other hand, since each of the fields of a structure is stored as an array of its own, it is up to you to enforce the fact that they have to match in length.
Some others posts if you want to read more about this: