Reputation: 40735
Right now I have this setup:
An NSMutableArray which stores two NSMutableArray instances.
A for-loop walks over a set of data and writes values into these arrays. It's for a big diagram / chart which is going to be displayed with OpenGL ES.
The NSMutableArray containing two other NSMutableArray objects is returned by a method, and the caller assigns it to a retaining property.
The pitty is this: There can be up to 2.000 values, and I don't like to create all those NSNumber objects.
Now I hope there's a lightweight way to do this with C.
Before I walk the loop I know the number of data points.
Now I want to refactor this so that I get lightweight C-arrays that hold just plain old float values. I know how to create a C-array of float values, but not really dynamically:
CGFloat values[ ] = {
0, 2.5f,
30.2f, 2.5f,
50.95f, 200.55f,
930.2f, 122.1f,
};
Questions:
1) How can I create an array like this dynamically in a loop?
2) How would I put two of those arrays into one array?
3) What about the memory managament? The method returns that multidimensional C-array, and the receiver needs to assign that to an instance variable (property). It needs to be kept around for a while. How could I create an instance variable to hold such an C-array, without knowing it's exact size in advance?
Upvotes: 4
Views: 1915
Reputation: 239041
For your first question, you can dynamically create an array using malloc()
, and use a pointer variable to store a reference to the first element of it. For example, this will create an array of 8 CGFloat
s:
CGFloat *a = malloc(8 * sizeof a[0]);
If a
is non-NULL, you can then access a[0]
through a[7]
in the usual way. You can return this CGFloat *
value to another function, and when you are done with the array, you must pass this value to free()
.
For second question, you can create an array of two pointers to the two dynamic arrays:
CGFloat *a[2] = { NULL, NULL };
a[0] = malloc(8 * sizeof a[0][0]);
a[1] = malloc(16 * sizeof a[1][0]);
You can now access a[0][0]
through a[0][7]
and a[1][0]
through a[1][15]
(as long as a[0]
and a[1]
are not NULL
).
However, there is a wrinkle here: You cannot directly return arrays in C, so you cannot return a
from a function anymore. You could instead use two levels of dynamic arrays, but it probably makes more sense to store the array of pointers within the retaining object in the first place, and pass a reference to this array to the function that fills it in.
This means that your containing object would include the CGFloat *a[2]
field, and your function that allocates the dynamic arrays and fills them would include a CFloat *dest[]
parameter. That function would start with something like:
dest[0] = malloc(8 * sizeof dest[0][0]);
dest[1] = malloc(16 * sizeof dest[1][0]);
...and then fill in the values as normal.
For the third question, the array that is created by malloc()
will live until that pointer is later passed to free()
. As mentioned, you can happily return that value and store it elsewhere, as long as you don't free()
it until you're done with it.
Upvotes: 3
Reputation: 17564
This will get you a new array:
CGFLoat* myArray = malloc(numberOfFloat * sizeof(float));
You can do things like myArray[6] = 0;
.
When you're done with it, you have to call free(myArray)
, or you will have a memory leak.
With this in mind, your instance variable will just be a CGFloat*
.
Upvotes: 3