Я передаю указатель на пользовательский тип функции, которая находится в памяти malloc
, и устанавливает этот указатель так, чтобы он указывал на нее. malloc()
возвращается с указателем, но когда я возвращаюсь из функции, мой указатель засоряется. Я придумал пару исправлений:
- вернуть указатель вместо его передачи
- передать адрес указателя, а не сам указатель
Я подозреваю, что это похоже на случай с FILE
указателями; если вы передадите указатель на функцию, вы не сможете рассчитывать на то, что указатель не будет изменен, потому что система может возиться с ним. Таким образом, вместо этого вы передаете адрес FILE *
.
У кого-нибудь есть объяснение этому? Вот код (извините, он немного длинный):
typedef struct {
BOOK *bookAry;
int numBooks;
}INVENTORY;
У меня было это в main()
, где INVENTORY
- это определенный пользователем тип, как указано выше:
//variable declarations
INVENTORY *inv = NULL;
//process
initInventory( inv, bookArySize );
processFile( inv );
Функция initInventory()
выглядит следующим образом:
void initInventory( INVENTORY *inv, int size ) {
//process
inv = ( INVENTORY * ) malloc( sizeof( INVENTORY ) );
//more code here....
return;
}//initInventory
Итак, мы возвращаемся к main()
(мы думаем) с inv
, указывающим на вновь выделенную память (а inv
указывает на структуру, которая имеет другие указатели). Только когда я передаю указатель inv
на processFile()
, он забивается, и когда я пытаюсь ссылаться на данные в структуре inventory
, я получаю нарушение прав доступа. При возвращении к main()
!
указатель становится недействительным
Это исправлено: main()
имеет:
//variable declarations
INVENTORY *inv = NULL;
//process
inv = initInventory( inv, bookArySize );
processFile( inv );
и initInventory()
изменено на это:
INVENTORY * initInventory( INVENTORY *inv, int size ) {
//process
inv = ( INVENTORY * ) malloc( sizeof( INVENTORY ) );
//return a pointer to the INVENTORY header struct
return inv;
}//initInventory
Тогда я попробовал это, что я считаю лучшим решением. main()
теперь имеет:
//variable declarations
INVENTORY *inv = NULL;
//more code here...
//process
initInventory( &inv, bookArySize );
processFile( inv );
А initInventory()
выглядит следующим образом:
void initInventory( INVENTORY **inv, int size ) {
//process
*inv = ( INVENTORY * ) malloc( sizeof( INVENTORY ) );
//more code here....
return;
}//initInventory