Newsgroup: it.comp.lang.c++
Titolo: Funziona solo in certi casi

Scusate se scrivo in questo NG ma it.comp.lang.c non esiste e cosi'
questo e' quello che ci si avvicina di piu'.
Ho un database dove i record sono di 4096 byte. Il problema e' che il
seguente programmino non riesce a leggere questi record.
(ovviamente qui ho le include necessarie)
int main(void)
    {
    FILE *M_STREAM;
    int i;
    unsigned char b[4096]="";
    for (i = 0; i <4096; i++) // Questo for c'e' solo per
        {                     // riempire l'array b in modo
        b[i] = '#';           // da vedere poi quanti caratteri
        }                     // vengono letti.
    M_STREAM = fopen("
database.cm
","a+b");
    fseek(M_STREAM, 0, SEEK_SET);
    fread(b, 4096, 1, M_STREAM);
    printf("\n\nb[4094]=%3d b[4095]=%3d", b[4094], b[4095]);
    }
La cosa strana e' che il programma funziona solo se viene compilato
usando il modello small mentre se passo in compact viene compilato ok
pero' invece di leggere 4096 byte ne legge solo 10.
Dalle varie prove fatte ho scoperto che funziona anche in compact ma
solo se gli dico di leggere al massimo 511 caratteri
(quindi : fread(b, 511, 1, M_STREAM);) ma ad esempio non funziona se
faccio : fread(b, 1, 4096, M_STREAM).
Come mai ???
Compilato con Borland C++ 4.5, Borland Turbo C++ 3.0 tutto in ambiente
Win95 con FAT32.
Bye/ciao
Verno Vito Valerio
ve...@ibm.net
Genoa - Italy

A parte che l'inizializzazione a stringa vuota dell'array e quella
printf non mi piacciono proprio, se =E8 vero quello che scrivi scrivi =
c'e'
un baco nella libreria. Hai provato a seguire passo passo nel debugger
quello che avviene ? Magari sfruttando i sorgenti della libreria per
evitare di incasinarti con l'assembler ?
Hai provato a aprire il file in read invece che in append ? In passato
ho visto dei bellissimi bachetti legati ai file aperti in append (altra
funzione storicamente a rischio: realloc).
---
     Andrea Ferro
SW.AN. Technologies s.a.s.
Merate (Lc)          Italy
	-----Original Message-----
	From:	
ve...@ibm.net
 (vito verno) [
SMTP:ve...@ibm.net
]
	Posted At:	Thursday, October 02, 1997 9:29 AM
	Posted To:	c++
	Conversation:	Funziona solo in certi casi
	Subject:	Funziona solo in certi casi
	Scusate se scrivo in questo NG ma it.comp.lang.c non esiste e
cosi'
	questo e' quello che ci si avvicina di piu'.
	Ho un database dove i record sono di 4096 byte. Il problema e'
che il
	seguente programmino non riesce a leggere questi record.
	(ovviamente qui ho le include necessarie)
	int main(void)
	    {
	    FILE *M_STREAM;
	    int i;
	    unsigned char b[4096]=3D"";
	    for (i =3D 0; i <4096; i++) // Questo for c'e' solo per
	        {                     // riempire l'array b in modo
	        b[i] =3D '#';           // da vedere poi quanti caratteri
	        }                     // vengono letti.
	    M_STREAM =3D fopen("
database.cm
","a+b");
	    fseek(M_STREAM, 0, SEEK_SET);
	    fread(b, 4096, 1, M_STREAM);
	    printf("\n\nb[4094]=3D%3d b[4095]=3D%3d", b[4094], b[4095]);


>Hai provato a aprire il file in read invece che in append ?
No, non ho provato anche perche' non posso aprirlo in read quindi
anche funzionasse mi metterei a piangere :-))


In realt=E0 non =E8 sbagliato quello che hai fatto. Ma di solito io non
inizializzo gli array automatici (cio=E8 non globali, ed evito le
globali), a parte che in C++ la cosa =E8 tutta diversa.=20
	strcpy(pippo, "");
	pippo[0] =3D NULL;
	pippo[0] =3D '\0';
La prima =E8 corretta, la seconda non =E8 portabile (NULL =E8 un =
puntatore non
un carattere) la terza =E8 corretta e corrisponde alla prima, ma =E8 =
pi=F9
efficiente e non linka strcpy, e quindi =E8 da preferire (la prima =
per=F2 =E8
leggermente pi=F9 leggibile, dipende da cosa vuoi ottenere).
La printf non mi piace perch=E8 dichiari di stampare un %d e poi passi =
un
char. Scrivila cos=EC:
printf(=93\n\nb[4094]=3D%3d b[4095]=3D%3d=94, (int)b[4094], =
(int)b[4095]);
L'idea di lavorare con i puntatori per bypassare le idiosincrasie dello
stack mi pare risolutiva ma stupida. Meglio aumentare lo stack con
l'apposita opzione di link. Ora non ricordo pi=F9 quale =E8 il =
paradigma
compact. Io ai tempi lavoravo cos=EC: sviluppa tutto in modello far/far
(credo fosse large). Poi valuta se ci sono forti necessit=E0 di =
migliorare
la velocit=E0 delle chiamate (con i processori successivi al 486/33 non =
=E8
pi=F9 un vero problema. Ma su un 286 a volte si) e la quantit=E0 di =
codice
totale =E8 piccola riduco i puntatori a codice a near ottenendo il =
modello
near_code/far_data (medium o compact ? non ricordo). Se e solo se il
programma =E8 estremamente piccolo sia in codice che dati passo a tiny =
e
creo un .com. Lo small non l'ho quasi mai usato. Se le mie strutture
richiedono pochi dati (meno di 64K in tutto stack compreso) ma
moltissimi sono puntatori allora riduco la dimensione dei puntatori =
dati
a near.
L'ideale =E8 comunque non usare ne near ne far come modificatori e
lavorare con il modello large. Di fatto su un pentium non cambia nulla
in termini di velocit=E0 e poco in termini di dimensione. Non ridurre =
le
dimensioni se non c'e' un vero motivo (per esempio se lavori con un
sistema embedded).
---
     Andrea Ferro
SW.AN. Technologies s.a.s.
Merate (Lc)          Italy
	-----Original Message-----
	From:	
ve...@ibm.net
 (vito verno) [
SMTP:ve...@ibm.net
]
	Posted At:	Wednesday, October 08, 1997 12:34 AM
	Posted To:	c++
	Conversation:	Funziona solo in certi casi
	Subject:	Re: Funziona solo in certi casi
	On Fri, 3 Oct 1997 02:09:23 +0200, in it.comp.lang.c++
	Andrea Ferro <And...@SWAN.it> wrote:
	>>A parte che l'inizializzazione a stringa vuota dell'array
	Anch'io a volte mi sono sono chiesto se inizializzare cosi' le
	stringhe e' corretto pero' considerando che :
	- il compilatore non dice nulla
	- la inizializza bene
	- l'esempio riportato nel manuale e' :
	  char name[] =3D { "Unknown" };
	  il manuale dice che le graffe sono optional quindi quello
	  che faccio di diverso e' di dire al compilatore la
	  lunghezza della stringa/array mentre l'esempio del manuale
	  la prende uguale alla stringa di inizializzazione
	Pensi forse che dovrei fare :
	char pippo[100];
	strcpy(pippo, "");
	Gia' che ci siamo, pensi che ci siano differenze a livello di
	correttezza, portabilita', velocita' e rispetto dello standard
tra le
	seguenti righe :
	strcpy(pippo, "");
	pippo[0] =3D NULL;
	pippo[0] =3D '\0';
	>>e quella printf non mi piacciono proprio
	Tu come faresti ? Se la stringa non e' altro che un array di
caratteri
	volendo analizzare un carattere in una certa posizione posso
benissimo
	andare a vedere l'elemento dell'array che m'interessa.
	>>se =E8 vero quello che scrivi scrivi c'e' un baco nella
libreria.
	Dopo varie prove e grazie ai suggerimenti ricevuti in NG si e'
	scoperto che e' un problema di stack. Infatti basta compilare le
	seguenti righe in modello Compact e abilitare il controllo dello
stack
	che subito esce "Stack overflow" mentre compilandolo in Small
non dice
	nulla (4099 e' il primo valore per il quale esce l'overflow, con
4098
	si riesce ancora ad eseguire) :
	int main(void)
	    {
	    char b[4099] =3D "";
	    return 0;
	    }
	Questo mi ha creato non pochi problemi in quanto nel programma
devo
	allocare alcune variabili di quelle dimensioni (non tante ma
anche 3/4
	sono una casino da gestire, appena ti muovi e cambi una virgola
te ne
	vai in overflow) e cosi' mi e' venuta l'idea di usare i
puntatori. Ad
	esempio invece di quello che ho scritto sopra faccio :
	char *b
	b =3D (char *) malloc(4099);
	in questo modo riesco a gestire molte piu' stringhe senza nessun
	problema di overflow.
	Quest'idea l'ho poi applicata anche in un altro punto del
programma
	dove creo una lista che pero' puo', in casi particolari, aver
bisogno
	di gestire stringhe lunghe. Ad esempio con il sistema che ho
sempre
	usato avrei fatto :
	struct LISTA
	    {
	    char nome_cognome[100];
	    char telefono[16];
	    struct LISTA *next;
	    } pippo;
	mentre usando i puntatori (e tante malloc) faccio :
	struct LISTA
	    {
	    char *nome_cognome;
	    char telefono[16];
	    struct LISTA *next;
	    } pippo;
	pippo.nome_cognome =3D (char *) malloc(quant'e' lungo il nome);


 leggermente più leggibile, dipende da cosa vuoi ottenere).
Per la leggibilita', di solito io uso pippo[0]=0x00; : la 'x' mi salta di
piu' agli occhi.
Inoltre, NULL in ANSI C++ e' definito, se non erro, proprio come 0. La
#define NULL ((void *)0) e' C.
Giusto per perdere due minuti.. :)
--
Cristiano Sadun - Software Engineering and Consulting
***********Remove NOSPAM from address to reply***********
*********************************************************
"God is Real - unless declared Integer"


Snip.
Capisco l'ambiguita'  del linguaggio naturale, ma mi pare che fosse
chiaro: in ANSI C++, NULL *e'* definito come 0. 'definizione', *non*
'semantica'. Chiaro? Ti e' nota la differenza?
Vatti a vedere dove viene definito, sul tuo compilatore. Troverai un
bel
 #ifdef __cplusplus
  #define NULL 0
 #else
  #define NULL ((void *)0)
 #endif
il che, per chi conosce il C++, e' del tutto corretto. Immagino che
saprai il perche'. :^)
In effetti, codice come
char str[10]; str[0]=NULL;
provoca un errore (o un warning, a seconda del compilatore) in C,
mentre e' legale (e semanticamente corretto) in C++.
Puo' essere cha la cosa sia stata definita cosi' proprio per permettere
quel tipo di assegnamenti, che rendono chiara l'inizializzazione
di un char *.
Sarebbe, comunque, carino leggere *attentamente* prima di fare
un post.
CS


 Giusto per perdere due minuti.. :)
NULL non è 0: è "un puntatore void inizializzato a 0" !!!!!!!!!
Punta all'indirizzo di memoria 0x000000!!!!!!!
Che è "completamente" diverso dal valore "int" 0!!!!!!!
Scusatemi lo sfogo....
-- 
                                                          ,,,
                                                         (0^0)
|--- Giovanni Petrillo ----------------------------- oOO__( )__OOo ---|
|    Italdata S.p.A.                                                  |
|    Software Division (PRS)                Tel: +39 825 621 560      |
|    Nucleo Industriale - Pianodardine      Fax: +39 825 621 501      |
|    83100 Avellino  (ITALY)                                          |
|                                                                     |
|__________ mailto:
Giovanni...@p1.ave1.itd.siemens.net
 _________|
|                                                                     |
  Keep it simple: as simple as possible, but no simpler - A. Einstein