これは、私が以前に尋ねた質問のフォローアップです。私はまだポインターの使い方を学んでいますが、データ構造を繰り返し処理しているときに、構造体の物理アドレスへの参照を維持するのが難しいと感じています。たとえば、検索ポインターを介して削除したい単純なベアボーン リンク リストがあります。
struct Node{
int value;
struct Node* next;
};
struct Node* createNode(int value){
struct Node* newNode = malloc(sizeof *newNode);
newNode->value = value;
newNode->next = NULL;
return newNode;
}
void nodeDelete(Node **killptr){
free(*killptr);
*killptr = NULL;
}
int main(){
struct Node* head = createNode(16);
head->next = createNode(25);
head->next->next = createNode(51);
head->next->next->next = createNode(5);
// Working code to delete a specific node with direct reference address
struct Node** killptr = &head->next;
nodeDelete(killptr);
return 0;
}
上記はnodeDelete
、先頭ポインタのアドレスにポインタを渡して削除することを示しています。私がやりたい->next
ことは、削除条件を満たすものが見つかるまでポインターを移動し、それを呼び出すことができるようにするnodeDelete
ことです。私は次のことを試しました:
struct Node* searchAndDestroy = head;
while(searchAndDestroy->value != NULL){ // Search until the end of the structure
if (searchAndDestroy->value == 25){ // If the value == 25
nodeDelete(&searchAndDestroy); // Delete the node (FAILS: Nullifies the
// address of search variable, not the
break; // original node)
}else{
searchAndDestroy = searchAndDestroy->next;
}
}
私はまた、次の行に沿って何かを試しました:
if (searchAndDestroy->value == 25){
struct Node** killptr = (Node**)searchAndDestroy);
nodeDelete(killptr); // Still fails
}
ポインタを ->next ポイントに移動できるようにする必要がありますが、(検索ノード自体のアドレスへの参照ではなく) 削除するノードのアドレスへの参照も維持する必要があります。
EDIT:いくつかの明確化:この方法でリンクされたリストから削除することは単純であり、メモリをリークし、リストの半分を不適切に削除することに気付きました。ポイントは、リンクされたリストから実際に削除することではありません。最終的には、これを使用して二分探索木の葉を再帰的に削除するという考えです。リンクされたリストは、例として質問に記載する方が短いと思いました。