Проблемы с созданием списка - PullRequest
0 голосов
/ 22 января 2019

Я создаю список, который читает данные из файла, и для каждой строки файла создает новый элемент списка.

На самом деле блокируется в Prod_ptr corrente_ptr = * lptr; по некоторым причинам, которые я не могу понять

Основная часть программы до цикла, в котором я создаю список:

int main (){
Prod_ptr *lptr = NULL ;
int count, i =  0 ;
char c;
short opzione;
    FILE *file_ptr;
void (*f[DIM])(Prod_ptr *lptr ) ={cambia_quantita , insert_prod, delete_prod ,  cambia_prezzo , cerca_prodotto , stampa_prod};
    file_ptr= fopen( "pischelletto.csv" , "r");
if(file_ptr==NULL) {
    printf("error program name");
    return 1;
}

for (c = getc(file_ptr); c != EOF; c = getc(file_ptr))
    if (c == '\n') // Increment count if this character is newline 
        count = count + 1; 

rewind(file_ptr);
for ( i =  0 ;  i < count ; i++ ){
    create_list_prod ( lptr , file_ptr);
}

Функция, которая создает список:

void create_list_prod ( Prod_ptr *lptr, FILE *file_ptr){
int code, price;
char nome[20];
    Prod_ptr nuovo_prod_ptr = malloc(sizeof(Lista_prodotti));
    fscanf( file_ptr , "%d;%s;%d;", &code , &nome , &price);
    if(nuovo_prod_ptr != NULL){
        nuovo_prod_ptr->product.codice = code;
        strcpy(nuovo_prod_ptr->product.nome_prod , nome);
        nuovo_prod_ptr->product.prezzo;
        nuovo_prod_ptr->product.quantita_magazzino = rand() % (100001); 
        nuovo_prod_ptr->prossimo_prod_ptr= NULL;

        Prod_ptr precedente_ptr = NULL;
        Prod_ptr corrente_ptr = *lptr;

            while( corrente_ptr != NULL || corrente_ptr->product.codice < nuovo_prod_ptr->product.codice){
                precedente_ptr = corrente_ptr;
                corrente_ptr = corrente_ptr->prossimo_prod_ptr;
        }
        if( precedente_ptr== NULL){
            nuovo_prod_ptr->prossimo_prod_ptr = *lptr;
            *lptr =  nuovo_prod_ptr;
        }
        else{
            precedente_ptr->prossimo_prod_ptr= nuovo_prod_ptr;
            nuovo_prod_ptr->prossimo_prod_ptr = corrente_ptr;
        }

}
else{
    puts("Memoria esaurita");
}

}

1 Ответ

0 голосов
/ 22 января 2019

in main

Prod_ptr *lptr = NULL ;

.. lptr not changed

for ( i =  0 ;  i < count ; i++ ){
  create_list_prod ( lptr , file_ptr);
} 

, поэтому вы звоните create_list_prod с lptr == NULL, а lptr по-прежнему NULLкогда вы делаете Prod_ptr corrente_ptr = *lptr;, так что вы читаете по адресу 0 => crash

, для меня строка должна быть Prod_ptr corrente_ptr = lptr;


, у вас также есть проблема в строке

while( corrente_ptr != NULL || corrente_ptr->product.codice < nuovo_prod_ptr->product.codice)

, потому что если corrente_ptr равен NULL, вы делаете corrente_ptr->product.codice и т. Д.

Должно быть

while( corrente_ptr != NULL && corrente_ptr->product.codice < nuovo_prod_ptr->product.codice)

Обратите внимание, что строка nuovo_prod_ptr->product.prezzo; ничего не делает


В предыдущей версии я сказал:

В строках

 nuovo_prod_ptr->prossimo_prod_ptr = *lptr;
 *lptr =  nuovo_prod_ptr;

должно быть

 nuovo_prod_ptr->prossimo_prod_ptr = lptr;
 lptr =  nuovo_prod_ptr;

но я ошибся


Вы не дали определение Prod_Ptr и т. д., поэтому я экстраполирую их ниже из вашего кода.

Я добавил комментарии в ваш код, чтобы объяснить дополнительные изменения. Iсделал, чтобы это работало хорошо.

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

/* 
   extrapolated definitions
*/

typedef struct Product {
  char nome_prod[20];
  int codice;
  int prezzo;
  int quantita_magazzino;
} Product;

typedef struct Lista_prodotti {
  struct Lista_prodotti * prossimo_prod_ptr;
  Product product;
}Lista_prodotti;

typedef Lista_prodotti * Prod_ptr;

/* */

void create_list_prod ( Prod_ptr *lptr, FILE *file_ptr) {
  int code, price;
  char nome[20];

  if (fscanf(file_ptr , "%d;%19[^;];%d;", &code , nome , &price) != 3) {
    puts("invalid values in the file, bypassed");
  }
  else {
    Prod_ptr nuovo_prod_ptr = malloc(sizeof(Lista_prodotti));

    if (nuovo_prod_ptr != NULL) {
      nuovo_prod_ptr->product.codice = code;
      strcpy(nuovo_prod_ptr->product.nome_prod , nome);
      nuovo_prod_ptr->product.prezzo = price;  /* I suppose */
      nuovo_prod_ptr->product.quantita_magazzino = rand() % (100001); 
      nuovo_prod_ptr->prossimo_prod_ptr= NULL;

      if (*lptr == NULL) {
        /* this is the first added cell of the list */
        *lptr = nuovo_prod_ptr;
      }
      else {
        Prod_ptr precedente_ptr = NULL;
        Prod_ptr corrente_ptr = *lptr;

        while( corrente_ptr != NULL && corrente_ptr->product.codice < nuovo_prod_ptr->product.codice){
          precedente_ptr = corrente_ptr;
          corrente_ptr = corrente_ptr->prossimo_prod_ptr;
        }
        if( precedente_ptr== NULL){
          nuovo_prod_ptr->prossimo_prod_ptr = *lptr;
          *lptr =  nuovo_prod_ptr;
        }
        else{
          precedente_ptr->prossimo_prod_ptr= nuovo_prod_ptr;
          nuovo_prod_ptr->prossimo_prod_ptr = corrente_ptr;
        }
      }
    }
    else{
      puts("Memoria esaurita");
    }
  }
}

int main (){
  Prod_ptr lptr = NULL; /* not "Prod_ptr *" */
  int count = 0, i; /* count must be initialized, not i */
  int c; /* must be an int rather than a char to be able to memorize EOF whatever it is */
  /* put in comment because not used : short opzione; */
  FILE *file_ptr;
  /* put in comment because not used : void (*f[DIM])(Prod_ptr *lptr ) ={cambia_quantita , insert_prod, delete_prod ,  cambia_prezzo , cerca_prodotto , stampa_prod}; */
  file_ptr= fopen( "pischelletto.csv" , "r");

  if(file_ptr==NULL) {
    printf("error program name");
    return 1;
  }

  for (c = getc(file_ptr); c != EOF; c = getc(file_ptr))
    if (c == '\n') // Increment count if this character is newline 
      count = count + 1; 

  rewind(file_ptr);

  for ( i =  0 ;  i < count ; i++ ){
    create_list_prod ( &lptr , file_ptr); /* give the address of lptr */
  }

  fclose(file_ptr); /* added */

  /* print the list to check, also free memory. 
     You may need to adapt if my extrapolated definitions are wrong  */
  while (lptr != NULL) {
    printf("%s : %d %d %d\n", 
           lptr->product.nome_prod,
           lptr->product.codice,
           lptr->product.prezzo,
           lptr->product.quantita_magazzino);
    Prod_ptr next = lptr->prossimo_prod_ptr;
    free(lptr);
    lptr = next;
  }

  return 0;
}

Если я помещу это содержимое в pischelletto.csv

12;aze;3;
34;qsd;2;
6;foo;123;

, то выполнение выдаст:

foo : 6 123 75961
aze : 12 3 71341
qsd : 34 2 22417

Выполнение по valgrind для проверки доступа к памяти / утечек памяти:

valgrind --leak-check=full ./a.out
==22125== Memcheck, a memory error detector
==22125== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==22125== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==22125== Command: ./a.out
==22125== 
foo : 6 123 75961
aze : 12 3 71341
qsd : 34 2 22417
==22125== 
==22125== HEAP SUMMARY:
==22125==     in use at exit: 0 bytes in 0 blocks
==22125==   total heap usage: 4 allocs, 4 frees, 688 bytes allocated
==22125== 
==22125== All heap blocks were freed -- no leaks are possible
==22125== 
==22125== For counts of detected and suppressed errors, rerun with: -v
==22125== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...