Почему печать членов структуры приводит к бреду? - PullRequest
0 голосов
/ 17 ноября 2018

Я пытаюсь распечатать и получить доступ к членам структуры, чтобы использовать некоторые данные, содержащиеся в.

У меня есть две структуры, первая из которых представляет собой двоичное дерево поиска и содержит дубликаты ключей. Я пытаюсь извлечь уникальные ключи и сохранить их в отдельной структуре.

Примечание: Я могу распечатать все уникальные ключи из структуры node из функции unique_key. Однако мне нужен доступ к этим уникальным ключам из основного. Таким образом, моя идея состояла в том, чтобы создать отдельную структуру и передать ее обратно в основную функцию.

Определение обеих структур:

/* structure containing duplicate keys */
struct node
{
    int KEY;
    char *command;
    char *duration; /* pointer to a char since it is of unknown size*/
    char *time;
    char *description;
    int count;
    struct node *left, *right;
};

/* structure to hold unique keys*/
 typedef struct {
    int KEY;
    char *command;
    char *duration; /* pointer to a char since it is of unknown size*/
    char *time;
    char *description;
 }unique;

Я использую служебную функцию для обхода дерева двоичного поиска. Эта функция снабжена указателем на двоичное дерево поиска *root и печатает все уникальные ключи.

/* A utility function to find deepest keys of BST */
/* This is done by extracting the key with the lowest count, 
since count member of node struct gets incremented each time it is read. */
unique* unique_key(struct node *root)
{   
    unique *temp = (struct unique *)malloc(sizeof(unique));
    if (root != NULL)
    {
        unique_key(root->left);
        if (root->count == 1) {
            //the printf statement below prints all unique keys
            //Somehow I need to access in the main function, thus my idea was to create a separate struct as explained above
            printf("%d(%d) -> %s %s %s %s \n", root->KEY, root->count, root->command, root->time, root->duration, root->description);
            temp->KEY = root->KEY;
            temp->command = root->command;
            temp->description = root->description;
            temp->duration = root->duration;
        }
        unique_key(root->right);
    }

    return temp;
}

Основной код водителя:

int main()
{
    /* Let us create following BST.  Passing values along with key */
    struct node *root = NULL;
    root = insert_node(root, 12, "C", "1200", "79", "Meeting");
    root = insert_node(root, 3, "C", "1300", "60", "Lunch");
    root = insert_node(root, 2, "C", "1400", "30", "Dinner");
    root = insert_node(root, 1, "C", "0600", "90", "Work");
    root = insert_node(root, 5, "C", "4300", "30", "Diyoor");
    root = insert_node(root, 7, "C", "5608", "30", "Dinner");
    root = insert_node(root, 9, "C", "1409", "35", "t");
    root = insert_node(root, 2, "C", "1600", "60", "play");
    root = insert_node(root, 2, "U", "1800", "88", "eve");

    printf("Inorder traversal of the given tree \n");
    inorder(root);  //prints all keys and subsequent values
    unique *data = NULL;
    data = unique_key(root); //prints only unique keys
    printf("%d %s\n", data[1].KEY, data[1].command); //cannot print keys in main function to access from here on
}

Пример вывода будет следующим. BST заполняется соответствующим образом, и все функции обхода работают хорошо.

Inorder traversal of the given tree
1(1) 2(3) 2(2) 2(1) 3(1) 5(1) 7(1) 9(1) 12(1)
Deepest unique keys of the given tree
1(1) -> C 0600 90 Work
2(1) -> U 1800 88 eve
3(1) -> C 1300 60 Lunch
5(1) -> C 4300 30 Diyoor
7(1) -> C 5608 30 Dinner
9(1) -> C 1409 35 t
12(1) -> C 1200 79 Meeting


-33686019  å, æ

Иногда появляются другие тарабарские символы, которые не отображаются выше.

Мой вопрос: как я могу распечатать и получить доступ к членам unique и почему я вижу тарабарщину? Любые предложения будут оценены.


EDIT:

Это уникальные ключи, которые я пытаюсь удержать в unique:

1(1) -> C 0600 90 Work
2(1) -> U 1800 88 eve
3(1) -> C 1300 60 Lunch
5(1) -> C 4300 30 Diyoor
7(1) -> C 5608 30 Dinner
9(1) -> C 1409 35 t
12(1) -> C 1200 79 Meeting

Я ожидал printf("%d %s\n", data[1].KEY, data[1].command);, чтобы вернуть 2 U.

Ответы [ 2 ]

0 голосов
/ 17 ноября 2018

В настоящее время ваш код проходит по дереву и может нормально его распечатать, но вы на самом деле не собираете никаких результатов при вызове unique_key внутри себя, и ваш тип возврата недостаточен для возврата списка вещей.(списку нужен конец, либо переменная размера, либо нулевое завершение).Вам нужно изменить свой код, чтобы фактически собрать результаты.Один из способов сделать это - использовать базовый вектор (саморасширяющийся массив), например:

struct MyVector {
  void **data;
  size_t head;
  size_t size;
};
MyVector new_MyVector(size_t initial_size)
{
  MyVector list = {
    .data = malloc(sizeof(void*) * initial_size),
    .head = 0,
    .size = initial_size,
  };
  return list;
}
void push_MyVector(MyVector *vec, unique *item)
{
  if (vec->head <= vec->size) {
    vec->data = realloc(*vec->data)
    vec->size *= 2;
  }
  vec->data[vec->head] = item;
  vec->head++;
}

, а затем использовать его следующим образом:

unique* unique_key(struct node *root, MyVector *list) {
  ...
  unique *left = unique_key(root->left);
  push_MyVector(list, left)
  ...
  unique *right = unique_key(root->right);
  push_MyVector(list, right)
  ...
}

Некоторые примечания: поскольку данныедвойной указатель, чтобы освободить вектор, вам нужно перебрать его и освободить каждый отдельный элемент.Я решил сделать данные двойным указателем, чтобы сделать ваш текущий код в основном совместимым, но было бы лучше сделать его одним указателем и напрямую заставить вашу функцию записывать в вектор.Также не реализовано расширение вектора, чтобы вам не хватило места, хотя с определенными размером головы и размера вы можете это сделать (просто посмотрите, как использовать realloc).

PS: этот код не проверен, но я надеюсь, что вы поняли основную идею

0 голосов
/ 17 ноября 2018

В массивах C индексируются от 0, а не от 1. Попытка получить доступ к data[1] Вы получаете доступ к мусору сразу после ваших данных. Printf должен использовать data[0], а не data[1].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...