2

基本的に、ツリーで構成されるコードを作成しました。これにより、各ツリーノードには、データを含む独自のリンクリストがあります (各 treeNode にもデータが含まれます)。そのため、各 treeNode は、その特定の treeNode に対して複数のデータ項目を持つことができます。

したがって、この構造体を作成するには、treenode を呼び出し、その treenode のアドレスを createListNode 関数に渡し、ListNode を呼び出します。私の混乱は本当にどこからメモリを解放する必要があるのですか? 0 を返す前のプログラムの終了時のみ。メインまたは他の場所で。すべての入力がツリーとリストに追加されると、ユーザーに名前を尋ね、その名前に適したデータのリンクされたリストを表示します。

乾杯。

TC

編集:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

typedef struct ListNode {
    char            *number;
    struct ListNode *next;
}ListNode;

typedef struct TreeNode {
    char            *name;
    ListNode        *numbers;
    struct TreeNode *left;
    struct TreeNode *right;
}TreeNode;

TreeNode* AddNode(TreeNode *, char *, char *);
void  AddNum(TreeNode *, char *);
void N_Print(TreeNode* root);
TreeNode* SearchTree(TreeNode* root, char *search);

int main(void) {
char my_string[50], name[25], number[25];
TreeNode *root = NULL;
while ((fgets(my_string, 50, stdin)) != NULL) {
        if (my_string[0] == '.')
            break;      
    sscanf(my_string, "%s %s", name, number); 
    root = AddNode(root, name, number);  
}   
N_Print(root);
free(root);
free(root->numbers);
return 0;
}

TreeNode* AddNode(TreeNode *root, char *name, char *number) {
int comparison;   
if (root == NULL) {
    root = (TreeNode*)calloc(1,sizeof(TreeNode));
    root->name = strdup(name); 
    root->left = root->right = NULL;      
    AddNum(root, number);
}else if ((comparison = strcasecmp(name, root->name)) < 0)
    root->left = AddNode(root->left, name, number);
else if ((comparison = strcasecmp(name, root->name)) > 0) {
    root->right = AddNode(root->right, name, number);
} else if ((comparison = strcasecmp(name, root->name)) == 0 ) {
    AddNum(root, number);
}       
return root;
}

void AddNum(TreeNode *tn, char *number) {
 ListNode *ln = (ListNode *)calloc(1, sizeof(ListNode));
 ln->number = strdup(number);
 ln->next = tn->numbers;
 tn->numbers = ln;
}

TreeNode* SearchTree(TreeNode* root, char *search) {
int comparison;
if (root == NULL) {
    return NULL;
} else if ((comparison = strcasecmp(search, root->name)) == 0) {
    return root;
} else if ((comparison = strcasecmp(search, root->name)) < 0) {
     return SearchTree(root->left, search);
} else if ((comparison = strcasecmp(search, root->name)) > 0) 
     return SearchTree(root->right, search);    
}

void N_Print(TreeNode* root) {
TreeNode* search_val;
char search[25];
while(1) {
    printf("Type a name please: ");
    scanf("%24s", search);
            if (search[0] == '.')
                    break;
    search_val = SearchTree(root, search); 
    if (search_val == NULL) {
        printf("NOT FOUND\n");
        continue;
    }
    ListNode* ln = search_val->numbers;
    while ( ln != NULL) {
            printf("%s\n", ln->number);
            ln = ln->next;
    }
}
}
4

7 に答える 7

4

不要になったメモリは解放する必要があります。もちろん、それはアプリケーションのニーズによって異なります。

ガベージ コレクション環境 (Java など) では、ガベージ コレクタは、何も指されていないときにメモリを解放します。これを出発点として、メモリへの参照を削除する前にメモリを解放する必要があります。

于 2011-11-28T23:38:53.400 に答える
3

最善の計画 (IMO) は、アクセスする必要がなくなった時点でメモリを解放することです。ただし、動的に割り当てられたメモリを少量しか使用しない場合は、プログラムの最後にすべてを実行しても、おそらく大きな違いはありません (すべてを追跡していると仮定します)。

于 2011-11-28T23:38:06.497 に答える
2

使用しなくなったら、メモリを解放します。プログラムが終了する前にそれが発生した場合は、戻る前に解放します。プログラムが何かを続けたいと思っていて、ツリーがもう必要ない場合は、ツリーを解放してプログラムを続行します。

たとえば、ツリー内のリンクされたリストがある段階で縮小する可能性がある場合は、使用されなくなったノードをすぐに解放する必要があります。

于 2011-11-28T23:39:24.753 に答える
2

それは簡単です:

必要がなくなったら、メモリを解放します。あなたの場合、ノードを削除する必要はないようですので、ノードを削除する心配はありません。プログラムが終了すると、自動的に解放されます。ただし、それを参照するすべてのポインタが範囲外になり、使用できなくなるすべてのメモリを削除する必要があることに注意してください。これにより、メモリ リークが発生する可能性があります。

于 2011-11-28T23:38:19.267 に答える
2

フリーストアから入手した資源が不要になったとき。したがって、 callocリソースを使用していないポイントに応じて、解放して開始できます。ただし、ダングリング リファレンスには注意してください。

于 2011-11-28T23:38:21.370 に答える
2

印刷が終わったときなど、不要になったらすぐにすべてのデータを解放できます。あなたの場合、これがプログラムのすべてである場合、カーネルは終了時にプログラムによって割り当てられたすべてのメモリを解放するため、実際には問題になりません。ただし、他のプログラムに使用できないメモリを消費することを意味するため、プログラムが実行され続けるかどうかは重要です。

タブを閉じた後にメモリを解放しなかった以前のバージョンの Firefox と少し似ています。プログラムは、メモリを解放することなく、ますます多くのメモリを要求し続けました。

于 2011-11-28T23:38:57.930 に答える
0

上記の誰もが言うように、不要になったら解放しますが、さらに、作成したのと同じレベルで解放することをお勧めします。これは、参照を渡している場合などにより複雑になります。

于 2011-11-29T23:03:17.060 に答える