Последняя строка в функции не выполняет то, что предполагалось.Код неясен до точки непроницаемости.
Похоже, что цель состоит в том, чтобы выделить массив int
из-за sizeof(int)
в первом выделении памяти.По крайней мере, если вы хотите выделить массив структурных указателей, вам нужно использовать sizeof(SomeType *)
, размер некоторого типа указателя (sizeof(void *)
подойдет).Как написано, в 64-битной среде это приведет к ужасным ошибкам.
Массив выделяется с заголовком структуры (ArrayHeader
), за которым следует собственно массив.Возвращаемое значение считается началом самого массива;ArrayHeader предположительно будет найден путем вычитания из указателя.Это безобразно, как грех, и не подлежит загрузке.Его можно заставить работать, но это требует особой осторожности и (как сказал Брайан Керниган) «если вы пишете код настолько умно, насколько это возможно, как вы собираетесь его отлаживать?».
К сожалению, последняя строка неверна:
void _arrayCreateSize( void ***array, int capacity )
{
(*array) = malloc( (capacity * sizeof(int)) + sizeof(ArrayHeader) );
((ArrayHeader*)(*array))->size = 0;
((ArrayHeader*)(*array))->capacity = capacity;
// printf("Test!\n");
*(char**)array += sizeof(ArrayHeader);
}
Добавляет sizeof(ArrayHeader) * sizeof(char *)
к адресу вместо предполагаемого sizeof(ArrayHeader) * sizeof(char)
.Поэтому в последней строке следует читать:
*(char *)array += sizeof(ArrayHeader);
или, как отмечено в комментариях и альтернативном ответе:
*(ArrayHeader *)array += 1;
*(ArrayHeader *)array++;
Попутно отмечу, что имя функции на самом деле не должно начинатьсяс подчеркиванием.Внешние имена, начинающиеся с подчеркивания, зарезервированы для реализации (компилятора C и библиотеки).
В связи с этим возникает вопрос: почему оператор printf()
исправляет вещи?Ответ заключается в том, что это решает проблему.У вас есть Heisenbug, потому что есть злоупотребление выделенной памятью, и наличие printf()
удается немного изменить поведение кода.
Рекомендация
- Выполнитьпрограмма под
valgrind
.Если у вас его нет, получите его. - Пересмотрите код, чтобы функция проверяла возвращаемое значение из
malloc()
и возвращала указатель на структуру для выделенного массива. - Используйте более понятный код, указанный в Michael Burr .