创建列表时出现问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了创建列表时出现问题相关的知识,希望对你有一定的参考价值。
我创建一个列表,从文件中读取数据,并为文件的每一行创建一个新的列表元素。
实际上它阻止了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 == '
') // 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");
}
}
答案
在主要
Prod_ptr *lptr = NULL ;
.. lptr not changed
for ( i = 0 ; i < count ; i++ ){
create_list_prod ( lptr , file_ptr);
}
所以你用lptr == NULL调用create_list_prod
,当你执行Prod_ptr corrente_ptr = *lptr;
时lptr仍然为NULL所以你在地址读取0 =>崩溃
对我来说,这条线必须是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等的定义,所以我在下面从你的代码中推断它们。
我在您的代码中添加了注释,以解释我为使其运行良好所做的其他更改。
#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 == '
') // 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
",
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)
以上是关于创建列表时出现问题的主要内容,如果未能解决你的问题,请参考以下文章
在片段java类中使用“this”和getLastSignedInAccount时出现错误[重复]
当 FragmentActivity 在 Android 中进入后台时出现 NotSerializableException