Ваше использование указателей выглядит отлично. Ваш malloc()
возвращает указатель на память на определенный тип указателя. Осмотрев свой небольшой код, я думал, что вы могли бы принести пользу с предложениями для него и контекста вашего двоичного пример дерева может быть использован в.
ЬурейеГо nameing конвенция
Struct декларация и ЬурейиЙ может быть сделаны в том же время. Это вопрос предпочтения. Общим соглашением для typedefs в C является его имя в форме someType_t
, чтобы иметь последовательный способ идентификации typedefs везде, где они используются.
обнуления распределяемой памяти
Я обычно использую calloc()
, а не malloc()
, потому что в отличие от malloc()
, calloc()
нули выделенной памяти.
Я могу добавить слово _safe
к имени функции распределения (по соглашению), чтобы указать, вернётся ли оно, оно преуспело (например, оно безопасно, поэтому нулевой флажок в вызывающем уровне не нужен).
безопасного распределение и контроль за ошибки выделения
Распределение делает нулевую проверку и отображает явный простой вне памяти сообщений, если не хватает памяти. Если в программе нет памяти, что обычно считается фатальным и оправданием выхода из программы, потому что, если в любом месте недостаточно памяти, все может повредиться повсюду. Это была бы очень редкая программа, которая бы изощренно справлялась с избыточным состоянием памяти, например, чтобы ее можно было ждать и повторять до тех пор, пока память не будет доступна снова, поэтому простое выключение является обычным явлением.Использование безопасных функций распределения сэкономит вам много нулевой проверки в вызывающем уровне.
Установка освободила указатели на NULL
Примечания установки освобожденного указателя на NULL. Если это делается последовательно, то указатель всегда можно определить как действительный или нет с помощью проверки NULL. Кроме того, освобождение NULL в большинстве систем - это NOP, поэтому вы можете снизить риск двойного освобождения (освобождение указателя более одного раза), что может привести к катастрофическим и трудным для диагностики ошибок, особенно в более крупных программах.
Простой пример двоичного дерева
(компилирует/работает)
#include <stdio.h>
#include <stdlib.h>
typedef struct Tree {
int key;
int data;
struct Tree *left, *right;
} tree_t;
// Dummy data just for example:
#define KEY 1
#define VAL 2
#define KEY2 3
#define VAL2 4
#define KEY3 5
#define VAL3 6
tree_t *node_create_safe(const int, const int);
void free_tree(tree_t *);
int
main() {
tree_t *rootNode = node_create_safe(KEY, VAL);
rootNode->left = node_create_safe(KEY2, VAL2);;
rootNode->right = node_create_safe(KEY3, VAL3);;
free_tree(rootNode);
rootNode = NULL;
}
/*
* node_create_safe() - allocates node, always returns pointer.
*
* Side effects: Terminates program on allocation failure.
*/
tree_t *
node_create_safe(const int key, const int data) {
tree_t *node = calloc(sizeof(struct Tree), 1);
if (node == NULL) {
fprintf(stderr, "out of memory\n");
exit(-1);
}
node->key = key;
node->data = data;
return node;
}
/*
* free_tree() - Recursively frees [sub]tree
*/
void
free_tree(tree_t *node) {
if (node->left != NULL)
free_tree(node->left);
if (node->right != NULL)
free_tree(node->right);
free(node);
}
Это указатель. 'tree_new' возвращает указатель-to -tree_type'. – jtbandes
Это возвращаемый тип функции. Это указатель в порядке ... –
Разрывы строк не являются специальными в C. Это так же, как вы написали 'tree_type * tree_new (...' в одной строке. – user2357112