2015-05-16 3 views
0

Начну с того, что я совершенно новичок в C, и сейчас я борюсь с некоторыми очень неинтуитивными ошибками. Я уже давно пытаюсь найти какое-то решение, но я всегда нахожусь в тупике.Графическое представление с динамическими связанными списками

Я пытаюсь создать пару функций для вставки и отображения графика через динамические связанные списки. Во время компиляции все работает отлично, но элементы, похоже, не отображаются хорошо. Фактически, как и на изображении ниже, отображается только первый элемент узла.

Итак, возникает вопрос, что вызывает эти ошибки и предупреждения, и что делать, чтобы удалить их?

enter image description here

Если вы посмотрите на код ниже, вы увидите, что она имеет несколько предупреждений (я не знаю, почему они появляются - я использую блоки кода в Ubuntu с компилятором GNU) а также проблемы при отображении элементов графика. Проблема наиболее вероятна в функции display_graph, но я не могу понять, где.

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

typedef struct AdjListNode { 
    int dest; 
    struct LIST_NODE *next; 
} LIST_NODE; 

typedef struct AdjList { 
    struct LIST_NODE *head; 
} ADJACENCY_LIST; 

LIST_NODE *create_node(int dest) { 
    LIST_NODE *nod; 
    if(dest<0) exit(0); 
    nod = (LIST_NODE*)malloc(sizeof(LIST_NODE)); 
    if(nod==NULL) { 
     printf("Problems at memory allocation!"); 
     exit(0); 
    } 
    nod->dest = dest; 
    nod->next = NULL; 
    return (LIST_NODE*)nod; 
} 

void display_graph(ADJACENCY_LIST *v) { 
    int s, i; 
    LIST_NODE *nod; 
    s = sizeof(v); 
    for(i=0;i<=s;i++) { 
     nod = v[i].head; 
     //citeste lista cu head in primul nod 
     while(nod!=NULL) { 
      printf("Data from node: %d \n", nod->dest); 
      nod = nod->next; 
     } 
    } 
} 

int main() 
{ 
    int n; //number of graph nodes 
    int i; //just a counter 
    int dest; dest = -1; //it's actually the "name" of the nodes. They must all be positive so I started negative 
    char c; 
    ADJACENCY_LIST *t; 
    printf("The number of nodes of the graph: "); 
    scanf("%d", &n); 
    t = (ADJACENCY_LIST*)malloc(n*sizeof(ADJACENCY_LIST)); 

    /* We make a loop for the nodes and each node has a while thru which I make the links */ 
    for(i=0;i<n;i++) { 
     c = 'D'; // Initializing 
     printf("Specify the links of the node %d with the others:\n", i); 
     int contor; contor = 0; 
     while(c=='D') { 
      LIST_NODE *nod; 
      printf("The link with node: "); 
      scanf("%d%*c", &dest); 
      if(dest>=0){ 
       nod = create_node(dest); 
       if(contor==0) t[i].head = (LIST_NODE*)nod; // just make the first node a head node 
      } else nod = NULL; 
      //verificam daca vrem sa continuam 
      printf("Do you want to link any other node to %d?(D to add, anything else STOP\n)", i); 
      c = getchar(); 
      contor++; //increment counter 
     } 
     // inchidem lista 
    } 
    display_graph(t); 
return 0; 
} 

Любая помощь будет принята с благодарностью!

EDIT: Как Christhofe (подтвердили проблему) и Абхишек ВАСИШТ указал размер вектора V возвращается на самом деле размер указателя.

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

|| === Сложение: Отладка в Grafuri1 (компилятор: GNU GCC компилятора) === | /home/marianpc/Anul_1/SDA/Grafuri1/main.c||In функция 'display_graph': | /home/marianpc/Anul_1/SDA/Grafuri1/main.c|33|warning: назначение из несовместимого типа указателя | /home/marianpc/Anul_1/SDA/Grafuri1/main.c|38|warning: назначение из несовместимого типа указателя | /home/marianpc/Anul_1/SDA/Grafuri1/main.c|28|warning: неиспользуемая переменная '[-Wunused-variable] | /home/marianpc/Anul_1/SDA/Grafuri1/main.c||В функции 'main': | /home/marianpc/Anul_1/SDA/Grafuri1/main.c|71|warning: назначение из несовместимого типа указателя | /home/marianpc/Anul_1/SDA/Grafuri1/main.c|76|warning: назначение из несовместимого типа указателя | || === Сборка завершена: 0 ошибок, 5 предупреждений (0 минут, 0 секунд) === |

Главное, что программа функционирует сейчас. Большое спасибо, ребята! Действительно полезно!

+0

определения Struct не следует typedef'd.typedef'ing загромождает код, приводит к недоразумениям, делает код более трудным для людей читать и загромождает пространство имен компилятора. предложите использовать имена тегов в определениях структур, тогда когда когда-либо необходимость объявления структуры (или передачи параметров) использует «struct tagname» – user3629249

+0

, общая практика (и для удобочитаемости) должна использовать только «все капиталы» для #define имен и констант , Предложите использовать аргумент «camel» для переменных, функций и т. Д. – user3629249

+0

в C, возвращаемое значение из malloc() и семейства функций не должно быть отлито. – user3629249

ответ

2

Попробуйте

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

typedef struct AdjListNode { 
    int dest; 
    struct LIST_NODE *next; 
} LIST_NODE; 

typedef struct AdjList { 
    struct LIST_NODE *head; 
} ADJACENCY_LIST; 

LIST_NODE *create_node(int dest) { 
    LIST_NODE *nod; 
    if (dest < 0) exit(0); 
    nod = (LIST_NODE*)malloc(sizeof(LIST_NODE)); 
    if (nod == NULL) { 
     printf("Problems at memory allocation!"); 
     exit(0); 
    } 
    nod->dest = dest; 
    nod->next = NULL; 
    return (LIST_NODE*)nod; 
} 

void display_graph(ADJACENCY_LIST *v,int values) { 
    int s, i; 
    LIST_NODE *nod; 

    for (i = 0; i < values; ++i) 
    { 
     nod = v[i].head; 
     printf("Data from node: %d \n", i); 
     while (nod != NULL) 
     { 
      printf("Data : %d \n", nod->dest); 
      nod = nod->next; 
     } 
    } 
} 

int main() 
{ 
    int n; //number of graph nodes 
    int i; //just a counter 
    int dest; dest = -1; //it's actually the "name" of the nodes. They must all be positive so I started negative 
    char* c = (char*)(malloc(sizeof(char))); 

    ADJACENCY_LIST *t; 
    LIST_NODE *last_added; 

    printf("The number of nodes of the graph: "); 
    scanf("%d", &n); 
    t = (ADJACENCY_LIST*)calloc(n,sizeof(ADJACENCY_LIST)); 

    /* We make a loop for the nodes and each node has a while thru which I make the links */ 
    for (i = 0; i < n; i++) { 
     //c = 'D'; // Initializing 
     printf("Specify the links of the node %d with the others:\n", i); 
     int contor; contor = 0; 
     do { 
      LIST_NODE *nod; 
      printf("The link with node: "); 
      scanf("%d", &dest); 
      if (dest >= 0) { 
       nod = create_node(dest); 
       if (contor == 0) 
       { 
        t[i].head = (LIST_NODE*)nod; // just make the first node a head node 
        last_added = nod; 
       } 
       else 
       { 
        last_added->next = nod; 
        last_added = nod; 
       } 
      } 
      //verificam daca vrem sa continuam 
      printf("Do you want to link any other node to %d?(D to add, anything else STOP\n)", i); 
      fflush(stdin); 
      *c = getchar(); 
      contor++; //increment counter 
     } while (*c == 'D'); 
    } 
    display_graph(t,n); 
    return 0; 
} 
+0

Спасибо за код! Протестировано, но появились некоторые ошибки. Опять же, из-за того же старого scanf, который не потреблял символ \ n, getchar не работал. Итак, добавлено scanf («% d% * c», &dest); и проблема решена - все узлы отображаются корректно. Кажется, что частью отображения была проблема, так как размер этого вектора v не возвращал n, но что-то другое , – marianstefi20

0

следующий код компилируется, работает.

У него нет возможности иметь список узлов для каждой записи в списке указателей первого уровня.

Вы можете легко добавить эту функцию.

Кроме того, необходимо добавить функцию прохождения каждого malloc'd узел, чтобы освободить() особенно когда ошибка произошла

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

struct AdjListNode 
{ 
    int dest; 
    struct AdjListNode *next; 
} ; 


// declare list of pointers to nodes 
static struct AdjListNode **head = NULL; 


struct AdjListNode *create_node(int dest) 
{ 
    struct AdjListNode *nod; 

    nod = malloc(sizeof(struct AdjListNode)); 
    if(nod==NULL) 
    { 
     perror(" malloc failed"); 
     printf("Problems at memory allocation!"); 
     exit(-1); 
    } 

    // implied else, malloc successful 

    nod->dest = dest; 
    nod->next = NULL; 
    return nod; 
} // end function: create_node 



int main(void) 
{ 
    int n; //number of graph nodes 
    int i; //just a counter 
    int dest = -1; //it's actually the "name" of the nodes. They must all be positive so I started negative 


    printf("The number of nodes of the graph: "); 
    if(1 != scanf("%d", &n)) 
    { // then scanf failed 
     perror("scanf for number of nodes failed"); 
     exit(-1); 
    } 

    // implied else, scanf successful 

    // set ptr to list of node pointers 
    head = malloc(n*sizeof(struct AdjList*)); 
    if(NULL == head) 
    { // then malloc failed 
     perror("malloc failed for list of pointers to nodes"); 
     exit(-1); 
    } 

    // implied else, malloc successful 

    // initialize list of pointers (makes for easier cleanup, especially when a failure occurs 
    memset(head, 0x00, n*sizeof(struct AdjList*)); 

    /* We make a loop for the nodes and each node has a while thru which I make the links */ 
    for(i=0;i<n;i++) 
    { 
     printf("Enter Dest value for %d of %d:", i, n); 

     if(1 != scanf("%d", &dest)) // note %d will skip over leading white space like newlines 
     { // then scanf failed 
      perror("scanf for dest value failed"); 
      exit(-1); 
     } 

     // implied else, scanf successful 

     if(dest>=0) 
     { 
      head[i] = create_node(dest); 
     } 
     else 
     { 
      printf("Dest value must be >= 0\n"); 
     } 

     //verificam daca vrem sa continuam 

     // inchidem lista 
    } // end for 

    return 0; 
} // end function: main