3

I have a handle-based class that I need to create a vector of. An easy method of doing this is to dynamically construct the vector in a for loop, but this causes mlint to complain about the changing vector size.

classdef HandleClass < handle
    ...
end

...

for i = 1:10
    foo(i) = HandleClass();
end

I'm suspicious of the resource-hit required to use this method to allocate large arrays of complicated objects.

A comment in a previous thread described a useful method to create a vector using the repmat function. However, @gnovice warned that doing that would create a vector of handles pointing to the same object. I have tested this and it appears to be the case.

Is there a trick that allows a vector of unique handle objects to be pre-allocated without the use of a for loop?


Solution Summary

The solution presented by SCFrench correctly allocates the memory for the creation of a vector of objects. Other solutions will create the vector, but will not allocate the memory.

foo(10) = HandleClass();
Community
  • 1
  • 1
Ryan Edwards
  • 633
  • 1
  • 10
  • 28
  • possible duplicate of [How to preallocate an array of class in MATLAB?](http://stackoverflow.com/questions/2510427/how-to-preallocate-an-array-of-class-in-matlab) – Amro Oct 27 '11 at 04:53

3 Answers3

4

Seems you can do this by a call to the empty method that is present in all non-abstract classes.

foo = HandleClass.empty(10,0);
for i = 1:10
    foo(i) = HandleClass();
end
Praetorian
  • 106,671
  • 19
  • 240
  • 328
  • This complains about a conversion error: _Conversion to double from HandleClass is not possible._ – Ryan Edwards Oct 24 '11 at 18:15
  • 1
    This shuts up M-Lint, but it doesn't actually preallocate anything. Try putting a 10000 element empty array into a variable and look at the Bytes column for that variable in the output of whos; it'll be around 100 bytes. Further, try timing this versus my solution (sample code at http://pastebin.com/Wn41Zhq9). I get a 60x speedup using my technique. – SCFrench Oct 25 '11 at 17:16
  • Thanks for doing the extra investigation, @SCFrench. I've changed my accepted answer to reflect. – Ryan Edwards Oct 28 '11 at 22:34
2
foo(10) = HandleClass();

This will default fill foo(1) through foo(9).

Note that this only works if HandleClass's constructor works with no input arguments (that is, it can be default-constructed).

SCFrench
  • 8,244
  • 2
  • 31
  • 61
  • Thanks. This works too, though I prefer @Praetorian's solution as it will let me use non-default constructors. – Ryan Edwards Oct 24 '11 at 18:55
  • 1
    When using this, be aware that this actually calls the constructor to initialize `foo(1)` to `foo(9)`. It may only be used when this as no side-effects. – Daniel Nov 05 '15 at 14:26
0

Having a default constructor the accepted answer is fine. Having no default constructor (HandleClass()) returns not enough input arguments) the best possibility I see is creating a cell first:

foo=cell(1,10);
for ix=1:10
    foo{ix}=HandleClass(ix)
end;
foo=[foo{:}];
Daniel
  • 36,610
  • 3
  • 36
  • 69