В рамках личного проекта я пытаюсь создать динамический массив из двух кортежей, которые показывают а) строку в программе и б) количество токенов байт-кода, связанных с этой строкой. Я реализовал это как структуру массивов:
typedef struct{
int count; // Number of elements
int capacity; // total capacity of arraylist
int* lines;
int* lineCount;
}
Это основано на примере из кодовой базы, например:
int count;
int capacity;
uint8_t* bytes;
Моя проблема связана с перераспределением -У меня есть несколько вспомогательных функций / макросов для увеличения и перераспределения памяти списков массивов - здесь, в частности, макрос GROW_ARRAY и reallocate (), как описано ниже. Когда я пытаюсь перераспределить lines
, он работает нормально, но я получаю ошибку сегментации и realloc(): invalid old size
несколько раз, когда я пытаюсь перераспределить lineCount после него
Я использую кодовую базу от БобаКрафт-интерпретаторы Nystrom, особенно эта первая часть здесь https://craftinginterpreters.com/chunks-of-bytecode.html#challenges. Большая часть кода взята оттуда, хотя и с некоторыми добавленными
В основном, я добавил много проверок и выполняю этусо всеми функциями отладки в gcc я могу найти. Примечательно, что realloc(): invalid old size
перестал появляться, так как я немного возился с кодом. РЕДАКТИРОВАТЬ: Добавлена основная функция, которая должна воспроизводить поведение
int main() {
LineArray lines;
// Initialize to 0 / NULL
initLineArray(&lines);
updateLineArray(&lines, 0, 1);
}
// the structure I'm using
typedef struct {
int capacity;
int count;
int* lines;
int* lineCount;
} LineArray;
/* Note LineArray has already been initialized earlier with
capacity=0;
count=0;
lines=NULL;
lineCount=NULL;
*/
void updateLineArray(LineArray* array, int line, int count) {
// IF line in `lines` -- update it
int index = containsLine(array, line);
if (index != -1) { // IF Index is not Error Code
// I think I fixed a bug here?
array->lineCount[index] += count;
return;
}
//ELSE -- add line to end (naturally appends); then increment
else {
//Check to see if array would be overgrown
if (array->capacity < array->count + 1) {
//IF yes, regrow array
int old_capacity = array->capacity;
array->capacity = GROW_CAPACITY(old_capacity);
// Reallocate arrays.
array->lines = GROW_ARRAY(array->lines, int, old_capacity,
array->capacity);
array->lineCount = GROW_ARRAY(array->lineCount, int, old_capacity,
array->capacity);
}
// Properly update the lines
array->lines[array->count] = line;
array->lineCount[array->count] = count;
array->count++;
return;
}
}
//The memory management functions/macros I'm using here
#define GROW_CAPACITY(capacity) \
((capacity) < 8 ? 8 : (capacity) * 2)
#define GROW_ARRAY(previous, type, oldCount, count) \
(type*) reallocate(previous, sizeof(type) * (oldCount), \
sizeof(type) * (count))
void* reallocate(void* previous, size_t oldSize, size_t newSize) {
// If size is null, erase it and get null_pointer
if (newSize == 0) {
free(previous);
return NULL;
}
// reallocate the data into a new size
// is Oldsize is zero :: malloc(data, newSize)
return realloc(previous, newSize);
}