PDA

Visualizza la versione completa : [C++] Limite dimensione file letto.


Angler84
13-01-2004, 22:46
Salve a tutti programmatori :D

Ho creato un programma per gestire un lista di films scritta su un qualsiasi file(file scritto in modo da avere un titolo di film per riga).
Ora il programma funziona alla perfezione se acquisisce un file con meno di 36 films.

Dal 36° in poi crasha inesorabilmente.... se sfora di poco si blocca lì mentre se il file supera i 70-80 interviene addirittura windows con una segnalazione errore. :eek:


Ora provando a debuggare noto che il porgramma riesce a gestire files con + dei fatidici 35 nomi senza problemi tranne nel bloccarsi in uscita. :jam:


Cosa potrebbe causare questo problema?

Il funzionamento in poche riga del programma è memorizzare i films dinamicamente in questo modo:
http://net.supereva.it/angler84/allocazione.JPG

Questo array poi viene gestito per riordinarlo, modificarlo, ecc.


Visto che il programma crasha subito quando crea l'array ( tranne quando è in modalità debugger :confused: ) il problema dovrebbe essere lì.

Il codice per generare il puntatore all'array di puntatori è questo:


char** array = new char*[num];
//num = numero films ricavato visualizzando una volta
il contenuto del file, questo lo senza problemi sempre.



A naso cosa potrebbe essere? :cry:
Eventualmente vi do pezzi di codice da vedere :)

Aiutatemi per favore che devo debuggarlo per giovedì prossimo :nonlodire

Angler84
14-01-2004, 16:48
up :(

cristiano_longo
14-01-2004, 17:02
puoi postare il messaggio di errore?

Angler84
14-01-2004, 17:34
Originariamente inviato da cristiano_longo
puoi postare il messaggio di errore?

Ora dopo un po' di smanettamento nn da + crash ma semplicemente si ferma il programma (dopo aver visualizzato correttamente tutti i nomi)per una trentina di secondi e poi si chiude da solo :confused:



Cmq un passo avanti:

In modalità debugger(senza creare punti di fermata) ha digerito tutti i 113 nomi con cui ho provato e ha fatto tutto quello che il progetto prevede senza il minimo errore :master:

Anzi un errore lo da bloccandosi alla deallocazione degli array :cry: . togliendola va che è una meraviglia :fagiano:



Resta sempre il problema che eseguendolo normalmente a volta va ( poche) e altre si pianta :mad:

Angler84
14-01-2004, 17:37
void elimina(int num, char** array){
for(int i=0; i < num; i++)
delete *(array+i);//libera i singoli spazi per i nome dei film
delete array;// elimina il puntatore all'array
cout << "\t---------------------------------\n"
<< "\t| Eliminazione Array completa |\n"
<< "\t---------------------------------\n";
return;
}



Questa è la funzione di Deallocazione.. nn è giusta? :master:
Per pochi nomi va per lunghe lista si pianta :cry:

P.S.: Tenete presente il modo con cui l'ho allocato.


P.P.S.: figata la colorazione del codice :adhone: ma xk php? :dottò:

cristiano_longo
14-01-2004, 17:37
Ma le stringhe all'interno dell'array le allochi anchesse dinamicamente?

Luc@s
14-01-2004, 17:39
Prova con questa mia classe:


// Parse.hpp
#ifndef PARSE_HPP_
#define PARSE_HPP_
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <map>

/**
Name:CParse \n
Author:Kleidemos \n
Description:Parser classs for generic text \n
*/
class CParse
{
public:
CParse(): _filename("prog.conf")
{ };
CParse(std::string name): _filename(name)
{ };
CParse(char * name): _filename(name)
{ };
~CParse(){};
/*
Permette di fare
string filename = <instanza>.FileConf()
o (per cambiarlo)
<instanza>.FileConf() = "prova"
*/
std::string& FileConf() { return _filename; };
void Read(const std::string &separator = "v");
void Write(const std::string &separator = "v", const std::string &key = "", const std::string &value = "");
void Test();
const std::string Find(const std::string &key);
private:
std::string _filename;
std::map<std::string, std::string> conf;
};

#endif

// Parse.cpp

#include "Parse.hpp"

/**
Name:Read\n
Return: -\n
Argouments: A separator [ DEFAULT: v ] \n
Description:Puts a generic config into internal buffer\n
*/
void CParse::Read(const string &separator)
{
std::ifstream in(_filename.c_str());
string code;
std::string key, value;
while(in)
{
in >> code;
if(code == separator) // a key find
{
in >> key >> value;
// inserisce i valori nella mappa
conf.insert(std::make_pair(key, value));
}
/*
Evito che valori diversi da quelli indicati da sepparator
vengano memorizzati.
Questo permette di usare commenti
*/
else
{
key = " ";
value = " ";
}
}
in.close();
}
/**
Name:Write\n
Return:-\n
Argouments:
- The name of options
- The value\n
- A separator [ DEFAULT: v ]
Description:Write a generic config value
*/
void CParse::Write(const std::string &separator, const std::string &key, const std::string &value)
{
std::ofstream out(_filename.c_str(), std::ios::app);
out << separator << " " << key << " " << value << "\n";
out.close();
}
/**
Name:Find\n
Return:A Value of option\n
Argouments: The name of option \n
Description: Find a option\n
*/
const std::string CParse::Find(const std::string &key)
{
return conf[key];
}
/**
Name:Test\n
Return:-\n
Argouments: -
Description: Test the class\n
ONLY FOR DEBUG
*/
void CParse::Test()
{
// Inserting
Write("dat", "prova", "si"); // write prova
Write("dat", "provas", "no");// write provas
Write("dat", "Schermo", "1024x768");// write Schermo
Write("so", "Schermos", "1024x768");// write error value
Write("no", "Schermos", "1024x768");// write error value
// Reading
Read("dat"); // puts read file
// Finding
cout << "Finding prova => " << Find("prova") << "\n";
cout << "Finding provas => " << Find("provas") << "\n";
cout << "Finding Schermo => " << Find("Schermo") << "\n";
cout << "Finding Schermos => " << Find("Schermos") << "\n";// try to find error value

}

Angler84
14-01-2004, 17:39
Originariamente inviato da cristiano_longo
Ma le stringhe all'interno dell'array le allochi anchesse dinamicamente?

Si tutto dinamico. O almeno nelle mie intenzioni :D

Nell'incertezza di scrivo il codice che ho creato per questa cosa:



// Crea un Array allocato dinamicamente contenente la lista dei films
// Restituisce l'indirizzo dell'array creato
char** creaarray(int num ,char nomefile[longmaxnomefile] ){
char** array = new char*[num]; //puntatore ad Array di puntatori contenente l'indirizzo dei nome dei film

ifstream lista( nomefile );
if(!lista) {
cerr << "\nErrore nel caricamento della lista.\n";
return NULL;
}

char datotemp[charmaxfilm]; //array temporaneo
int i=0;
while(lista.peek()!= EOF)
{
lista.getline(datotemp,charmaxfilm); //copio il nome nell'array temporaneo
array[i] = new char[strlen(datotemp)]; //creo dinamicamente un array di esatte dimensioni
strcpy(array[i], datotemp); //ci copio il nome film
i++;
}
lista.close();

cout << "\t---------------------------------\n"
<< "\t| Array Caricato con Successo |\n"
<< "\t---------------------------------\n";
return array;
}

Angler84
14-01-2004, 17:42
Originariamente inviato da Luc@s
Prova con questa mia classe:
[...]
[/CODE]

Ti ringrazio davvero ma le classi non le abbiamo fatto al corso e non so dove mettrci mano ne come usarlo.. o solo una vaga idea di cosa siano ma proprio 0 su come possa usarla :cry:

cristiano_longo
14-01-2004, 17:44
a me sembra buono. Al limite puoi provare ad aggiungere

strcpy(array[i], datotemp,charmaxfilm);

Ma sei sicuro che il probl non sia in "lista"?

Loading