Как построить массив C как этот динамически в цикле, вернуть его и сохранить ссылку? - PullRequest
4 голосов
/ 06 июля 2011

Прямо сейчас у меня есть такая настройка:

NSMutableArray, в котором хранятся два экземпляра NSMutableArray.

Цикл for обходит набор данных и записывает значения в эти массивы.Это для большой диаграммы / диаграммы, которая будет отображаться с OpenGL ES.

NSMutableArray, содержащий два других объекта NSMutableArray, возвращается методом, и вызывающая сторона назначает его сохраняющему свойству.

Суть в том, что может быть до 2000 значений, и я не люблю создавать все эти объекты NSNumber.

Теперь я надеюсь, что есть простой способ сделать это с C.

Перед тем, как идти по циклу, я знаю количество точек данных.

Теперь я хочу реорганизовать это, чтобы получить облегченные C-массивы, которые содержат просто старые значения с плавающей точкой.Я знаю, как создать C-массив значений с плавающей точкой, но на самом деле не динамически:

CGFloat values[ ] = {
    0, 2.5f,
    30.2f, 2.5f,
    50.95f, 200.55f,
    930.2f, 122.1f,
};

Вопросы:

1) Как я могу динамически создавать такой цикл в цикле?

2) Как бы я поместил два из этих массивов в один массив?

3) Как насчет управления памятью?Метод возвращает этот многомерный C-массив, и получатель должен назначить его переменной экземпляра (свойству).Это должно быть сохранено некоторое время.Как я могу создать переменную экземпляра для хранения такого C-массива, не зная заранее его точного размера?

Ответы [ 2 ]

3 голосов
/ 06 июля 2011

По первому вопросу вы можете динамически создать массив, используя malloc(), и использовать переменную-указатель для хранения ссылки на его первый элемент. Например, это создаст массив 8 CGFloat s:

CGFloat *a = malloc(8 * sizeof a[0]);

Если a не равен NULL, вы можете получить доступ от a[0] до a[7] обычным способом. Вы можете вернуть это значение CGFloat * другой функции, и когда вы закончите работу с массивом, вы должны передать это значение в free().

По второму вопросу вы можете создать массив из двух указателей на два динамических массива:

CGFloat *a[2] = { NULL, NULL };

a[0] = malloc(8 * sizeof a[0][0]);
a[1] = malloc(16 * sizeof a[1][0]);

Теперь вы можете получить доступ с a[0][0] через a[0][7] и a[1][0] до a[1][15] (если a[0] и a[1] не NULL).

Однако здесь есть морщина: вы не можете напрямую возвращать массивы в C, поэтому вы больше не можете возвращать a из функции. Вместо этого вы могли бы использовать два уровня динамических массивов, но, вероятно, имеет смысл сначала сохранить массив указателей внутри сохраняющего объекта и передать ссылку на этот массив функции, которая его заполняет в.

Это означает, что ваш содержащий объект будет содержать поле CGFloat *a[2], а ваша функция, которая выделяет динамические массивы и заполняет их, будет включать параметр CFloat *dest[]. Эта функция будет начинаться с чего-то вроде:

dest[0] = malloc(8 * sizeof dest[0][0]);
dest[1] = malloc(16 * sizeof dest[1][0]);

... и затем заполните значения как обычно.

Что касается третьего вопроса, массив, созданный malloc(), будет жить до тех пор, пока этот указатель не будет позже передан в free(). Как уже упоминалось, вы можете с радостью вернуть это значение и сохранить его в другом месте, если только вы не free() пока не закончите с ним.

3 голосов
/ 06 июля 2011

Это даст вам новый массив:

CGFLoat* myArray = malloc(numberOfFloat * sizeof(float));

Вы можете делать такие вещи, как myArray[6] = 0;.

Когда вы закончите с этим, вы должны позвонить free(myArray)или у вас будет утечка памяти.

С учетом этого ваша переменная экземпляра будет просто CGFloat*.

...