Я заметил пару странностей в коде.
Во-первых, сигнатура функции openFile
имеет тип возврата void
, но вы проверяете возвращаемое значение здесь:
if (openFile(file, &buf, fileData, fileDataLen) < 0)
Во-вторых, как Петр также указываетout, вы не выделяете достаточно места при вызове realloc
:
fileData = realloc(fileData, (*fileDataLen) * sizeof(struct fileInfo*));
На первой итерации, где (*fileDataLen) == 0
, после увеличения *fileDataLen
у вас теперь есть только значение 1
Это означает, что вы ничего не перераспределяете (т.е. вы просто возвращаете память, на которую уже указывал fileData
, поскольку она не изменила размер выделенного массива).Поэтому в следующий раз, когда вы вызовете fileData[(*fileDataLen)] = currFile;
во время другого рекурсивного вызова, вы скопируете значение currFile
в fileData[1]
, но эта память еще не была выделена.Кроме того, при следующем вызове realloc
он больше не сможет перераспределять память в том же месте, поэтому fileData
будет указывать на совершенно другое место, с копированием только первой записи массива.
В-третьих, вы не можете вызвать free(fileData)
в func1()
, поскольку вы, вызвав realloc
внутри своей функции func2()
, изменили значение того, куда указывает память, и вы не передаете фактическую памятьадрес исходной переменной fileData
по ссылке на вашу функцию func2()
.Другими словами, если вызов malloc()
в func1()
вернул значение, скажем, 0x10000, и вы вызвали realloc
для этой выделенной памяти где-то еще в коде, память, которая была выделена в 0x10000, теперь переместилась куда-то еще, но значение fileData
в контексте локальной области действия func1()
по-прежнему равно 0x10000.Таким образом, когда вы эффективно вызываете free(0x10000)
, что происходит при вызове free(fileData)
, вы получите ошибку, так как память для массива больше не выделяется в 0x10000.Чтобы освободить массив, вам либо придется возвращать обновленный указатель на массив указателей из всех рекурсивных вызовов func2()
, либо передавать fileData
по ссылке, что означает сигнатуру функций func2()
и openFile()
нужно будет изменить на тип fileInfo***
, и вам также понадобится дополнительный уровень косвенности при доступе к fileData
в func2()
и openFile()
.Затем, когда вы вызываете realloc
где-либо еще, вы фактически изменяете значение fileData
, как оно было также выделено в func1()
, и можете вызывать free()
для этого указателя.
Наконец, продолжайтепомните, что если вы освобождаете только память, выделенную для fileData
, у вас будет большая утечка памяти для всех выделенных fileInfo
узлов в куче, поскольку fileData
был только массивом указателей на узлы, а несами фактические узлы.