Измените функцию на:
HEADER *createHeader(void)
{
HEADER *yourHeader = malloc(sizeof(HEADER));
if (yourHeader == NULL)
printErrorAndExit();
yourHeader->first = NULL;
yourHeader->last = NULL;
yourHeader->length = 0;
return yourHeader;
}
Использование:
Header *header = createHeader();
if (header == NULL)
exit(-1);
В качестве альтернативы используйте указатель на указатель в качестве аргумента:
void createHeader(HEADER **yourHeader)
{
*yourHeader = malloc(sizeof(HEADER));
if (*yourHeader == NULL)
printError();
(*yourHeader)->first = NULL;
(*yourHeader)->last = NULL;
(*yourHeader)->length = 0;
}
Использование:
Header *header = NULL;
createHeader(&header);
if (header == NULL)
exit(EXIT_FAILURE);
Эти два метода могут применяться к большинству операций «указатель выделения» - создание связанных списков является наиболее распространенным вариантом. Обратите внимание, что fopen()
и fclose()
соответствуют первой модели; распределитель (fopen()
) принимает некоторые аргументы, чтобы сказать ему, что делать, и функция возвращает указатель на структуру, которая может быть использована и в конечном итоге передана в fclose()
для освобождения.
Обратите внимание, что printErrorAndExit()
не должен возвращаться. Или, если это так, функции должны быть пересмотрены:
HEADER *createHeader(void)
{
HEADER *yourHeader = malloc(sizeof(HEADER));
if (yourHeader == NULL)
printError();
else
{
yourHeader->first = NULL;
yourHeader->last = NULL;
yourHeader->length = 0;
}
return yourHeader;
}
Возможно, для функции было бы лучше не печатать никаких сообщений об ошибках - это ограничивает ее повторное использование, в целом.
HEADER *createHeader(void)
{
HEADER *yourHeader = malloc(sizeof(HEADER));
if (yourHeader != NULL)
{
yourHeader->first = NULL;
yourHeader->last = NULL;
yourHeader->length = 0;
}
return yourHeader;
}
Альтернативный дизайн, вероятно, должен возвращать статус, а не ничего, поэтому вы можете напрямую проверить результат функции:
int createHeader(HEADER **yourHeader)
{
int rc = 0;
*yourHeader = malloc(sizeof(HEADER));
if (*yourHeader == NULL)
rc = -1; /* Or perhaps errno */
else
{
(*yourHeader)->first = NULL;
(*yourHeader)->last = NULL;
(*yourHeader)->length = 0;
}
return rc;
}
Использование:
if (createHeader(&header) != 0)
…report error and bail out…
Использование 0 для успеха и ненулевое значение для сбоя очень распространено (многие системные вызовы Unix попадают в эту категорию). Очень часто отрицательное возвращаемое значение указывает на неудачу, особенно если положительное значение может быть использовано для успеха - подумайте open()
. Но функции POSIX pthread часто возвращают положительное число ошибок при сбое и ноль при успехе.