Существуют различные проблемы с вашим кодом (указано в комментариях и других ответах).Одна важная вещь, которую вы упускаете, это то, что вы не отслеживаете размер выделенной области.sizeof()
оценивается во время компиляции (если вы не используете C99 VLA).Таким образом, выполнение sizeof(rle)
не приведет к количеству байтов, которые использует ваш массив.Вы должны хранить это отдельно.Вот рабочая реализация, которая отслеживает размер с помощью структуры struct rle_parent
с комментариями, которые помогут вам понять:
#include <stdio.h>
#include <stdlib.h>
struct rle_element {
int length;
char character;
};
struct rle_parent {
struct rle_element *arr;
size_t count;
};
static void get_rle(struct rle_parent *p, int length, char character) {
struct rle_element *e;
/* Allocate enough space for the current number of elements plus 1 */
e = realloc(p->arr, (p->count + 1) * sizeof(struct rle_element));
if (!e) {
/* TODO: (Re)allocation failed, we should handle this */
return;
}
/* Update the parent to point to the reallocated array */
p->arr = e;
/* Update our newly added element */
e = &p->arr[p->count];
e->length = length;
e->character = character;
/* Bump the count so we know how many we have */
p->count++;
}
int main() {
struct rle_parent p;
size_t i;
/* Initialize */
p.arr = NULL;
p.count = 0;
get_rle(&p, 10, 'a');
get_rle(&p, 20, 'b');
get_rle(&p, 30, 'c');
/* Print out our array */
for (i = 0; i < p.count; i++) {
struct rle_element *e = &p.arr[i];
printf("%d -- %c\n", e->length, e->character);
}
return 0;
}
В качестве альтернативы, если вы не хотите вести подсчет, вы можете добавить другое поледо struct rle_element
, что указывает на то, что это последний элемент в массиве.Вам придется обновлять его каждый раз, когда вы добавляете новый элемент (очищая его в «текущем» последнем элементе и устанавливая его в «новом» последнем элементе), но в этом случае вы можете избавиться от struct rle_parent
.
Кроме того, передача NULL
в качестве первого аргумента realloc()
, заставляет его вести себя как вызов malloc()
, поэтому здесь все работает чисто.