所以首先我有兩個鏈表,一個在另一個里面(就像一個矩陣),我做了一個函式來洗掉整個節點。它似乎正在釋放,但是當我列印值 t 時,它會輸出奇怪的字符。
這是串列中使用的結構
typedef struct
{
char codigo[LEN_CODIGO 1];
char partidaID[LEN_ID 1];
char chegadaID[LEN_ID 1];
Data datapartida;
Tempo horapartida;
Tempo duracao;
Data datachegada;
Tempo horachegada;
int capacidade;
int ocupacao;
} Voo;
typedef struct r
{
char *codReserva;
int nPassangeiros;
struct r *next;
} *ListaReservas;
typedef struct node
{
Voo voo;
ListaReservas nodeReservas; /*this is the head to a list inside this list*/
struct node *next;
} *Node;
在下面的函式中,我假裝洗掉一個節點和其中的所有 nodeReservas 節點,就像洗掉矩陣的一整列一樣。
Node eliminaNode(Node head, char codigo[])
{
Node n, prev;
ListaReservas r, temp;
for (n = head, prev = NULL; n != NULL; prev = n, n = n->next)
{
if (strcmp(n->voo.codigo, codigo) == 0) /*If it's the correct node*/
{
if (n == head)
head = n->next;
else
prev->next = n->next;
/*deletes nodeReservas*/
r = n->nodeReservas;
temp = r;
while(temp != NULL)
{
temp = temp->next;
free(r->codReserva);
free(r);
r= temp;
}
/*deletes the whole node*/
free(n);
}
}
return head;
}
然后我使用此代碼告訴我節點中仍存在哪些保留
for (r=n->nodeReservas; r != NULL; r= r->next)
printf("%s %d\n", r->codReserva, r->nPassangeiros);
例如,在添加 3 個預留到讓我們說節點 X 并使用 eliminaNode(headofList, X) 洗掉具有預留的節點之后。在重新創建具有相同名稱“X”的節點并列印其保留后,我得到的不是空行,而是:
-725147632
? ???U -725147632
@ ???U -725147632
那么什么是 free() 釋放?發生這種情況是因為 Lista reservas 是一個指標嗎?
uj5u.com熱心網友回復:
free()將分配的塊回傳到堆中,在堆中它可以重新用于后續的分配請求。它不會(怎么可能?)修改指向該塊的指標,如果您保留這樣的指標并在取消分配后重新使用它,則不會發生任何好事。
您應該做的是在釋放塊后立即將指標設定為 NULL(或有效指標,例如新下一個節點的指標),這樣您就不會保留對現在無效塊的參考:
free(r->codReserva);
r->codReserva = NULL ;
free(r);
r= temp;
}
/*deletes the whole node*/
free(n);
n = NULL ;
這樣做應該是 C 代碼中的一種習慣。你可以通過創建一個函式來讓事情變得更簡單說:
void dealloc( void** ref )
{
free( *ref ) ;
*ref = NULL ;
}
然后,而不是打電話給free( n )你dealloc( &n ),例如。
此代碼還有其他嚴重問題。例如,涉及的代碼temp有點過于復雜(任何帶有變數的代碼temp都應該敲響警鐘——你已經為它賦予了整個函式的范圍,并將其用于多個目的——這不是一個好習慣)。考慮:
r = n->nodeReservas;
while( r != NULL)
{
ListaReservas new_next= r->next;
free(r->codReserva);
r->codReserva = NULL ;
free(r);
r = new_next;
}
有new_next非常本地化(字面意思是“臨時”)并適當命名,因此很清楚它是什么。下一個問題是,分配了值r后,您什么也做不了!大概n->nodeReservas是你打算更新不r?也許:
ListaReservas r = n->nodeReservas;
while( r != NULL)
{
ListaReservas new_next= r->next;
free(r->codReserva);
r->codReserva = NULL ;
free(r);
n->nodeReservas = new_next;
}
請注意在每種情況下在第一次使用時宣告臨時變數,以提供最窄的范圍。請注意,這r也是暫時的。然而在這里它并不是真正必要的——它只是一個簡寫n->nodeReservas——我個人會根除它——如果只是為了避免上面描述的錯誤。對單個分配有多個參考是錯誤的秘訣。反而:
while( n->nodeReservas != NULL)
{
ListaReservas new_next = n->nodeReservas->next;
free(n->nodeReservas->codReserva);
n->nodeReservas->codReserva = NULL ;
free(n->nodeReservas);
n->nodeReservas = new_next;
}
我不能肯定地說沒有其他錯誤 - 那只是具有明顯“代碼氣味”的部分。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/462795.html
