Newsgroup: it.comp.programmare.win32
Titolo: Strano errore allocazione & fscanf

Ciao a tutti,
vorrei avere delucidazioni su uno strano errore che mi capita in 3
linee di codice dopo una banale modifica:
Ho una struttura cosi' definita:
typedef struct tagRecordInfo
{
char Field[24];
char Type[4];
int Size;
int Pos;
} RecordInfo;
Codice funzionante:
RecordInfo ri[128];
int numfields=0;
while (fscanf(file,"%s %s %d
%d",ri[numfields].Field,ri[numfields].Type,&ri[numfields].Size,&ri[numfields].Pos)!=EOF)
	numfields++;
Ovviamente supponiamo numfields<128.
Ora modifico la dichiarazione di ri:
RecordInfo *ri;
ri=new RecordInfo[128];
int numfields=0;
while (fscanf(file,"%s %s %d
%d",ri[numfields].Field,ri[numfields].Type,&ri[numfields].Size,&ri[numfields].Pos)!=EOF)
	numfields++;
Quando il file finisce, indipendentemente dal valore di numfields
(sempre <128) e dalla dimensione di ri in debug CodeGuard (lo uso
insieme al BC 5.02a) mi rileva un access overrun sulla linea della
fscanf all'interno dell'area heap allocata etc etc.
Insomma con l'allocazione dinamica ottengo uno "svaccamento"
(passatemi il termine poco tecnico) della fscanf ma non capisco
perche' in quanto per me le due dichiarazioni sono equivalenti.
Avete suggerimenti ?
Ciao
Stefano
PS.
Forse il questo e' da it.comp.c, nel caso lo riposto di li'.
Stefano "HappyMan" (Lago Maggiore - NO)
--
http://www.sgr.info
Email happyman69 (at) 
libero.it

 Forse il questo e' da it.comp.c, nel caso lo riposto di li'.
o forse it.comp.lang.c++ ... o forse meglio ancora uno dei gruppi di 
discussione sul borland che si possono vedere dal server 
newsgroups.borland.com
  e in particolare il gruppo 
borland.public.cppbuilder.language.cpp
Ciao,
g.

Ti da errore anche senza CodeGuard ?
Per ora non ho provato, ma mi fido quasi "ciecamente" di CodeGuard:
tutti i casi un cui mi ha segnalato qualche problema, anche a prima
vista incomprensibile, alla fine aveva ragione...
Inoltre tale overrun potrebbe anche verificarsi senza CodeGuard ma non
dare un crash immediato (mi e' già capitato, tali overrun sono i piu'
balordi da scoprire...)
Ciao 


leggo...
Guardando velocissimamente il tuo codice (e sottolineo il
"velocissimamente") mi è sembrato che non vi fosse nulla di strano.
Controllerò meglio appena posso, però come regola generale, mi sento
di sconsigliarti l'uso di scanf() e sorelle, per tutte le operazioni
di lettura.  Piuttosto, usa fgets() ed esegui manualmente un parsing
dei parametri, ti toglie davanti un bel pò di problemi.
-- 
Andrea Laforgia
#exclude <windows.h>


Ciao,
ovviamente hai supposto numfields < 128.
Sei comunque sicuro che tutti i campi dei record che stai leggendo da file
rispettino le dimensioni che hai deciso nella tua struttura tagRecordInfo?
Parlo dei campi Field e Type, che essendo di 24 e di 4 char ciascuno, si
aspettano di essere riempiti da stringhe di non piu' di 23 e di 3 caratteri.
Basta che nel file ci siano stringhe superiori di dimensioni, specie per
l'ultimo record, ed avrai uno straboccamento nell'heap.
Magari con l'allocazione statica il problema c'era ma rimaneva invisibile
perche' sporcavi un'altra zona di memoria meno vitale.
Maurus

perche' sporcavi un'altra zona di memoria meno vitale.
Si si, controllato tutto con un file "sicuro".
In effetti il codice e' talmente banale e le situazioni al contorno
testate e controllate che non so che pesci prendere. Non che la
modifica sia essenziale, tutt'altro...pero' 'ste cose mi fanno prudere
le dita :-)
Per completezza di informazioni posto anche il messaggio del log di
CodeGuard:
Error 00004. 0x130410 (Thread 0x0114):
Access overrun: Attempt to access 6841 byte(s) at 0x016D8DF4, that is
at
 offset 72 in heap block 0x016D8DAC which is only 6912 bytes long.
fscanf(0x00447FB0, 0x00444270 ["%s %s %d %d"], 0x016D8DF4
["™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™
Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™
Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™
Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™
Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™
Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™
Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™
Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™
Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™
Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™
Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™
Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™
Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™Š™
Š™Š™Š™Š™Š™Š™"], ...)
Call Tree:
   0x00408318(=dbgate.exe:0x01:007318) connect.cpp#1061
   0x00415267(=dbgate.exe:0x01:014267) connect.cpp#4672
   0x77E12E98
   0x77E21A8C
   0x77E149FC
   0x77E15B27
The object array (0x016D8DAC) [size: 6912 bytes] was created with
new[]
Call Tree:
   0x00408262(=dbgate.exe:0x01:007262) connect.cpp#1059
   0x00415267(=dbgate.exe:0x01:014267) connect.cpp#4672
   0x77E12E98
   0x77E21A8C
   0x77E149FC
   0x77E15B27
In questo caso avevo dato
ri=new RecordInfo[192];
e i campi che leggo al max sono lunghi 7 byte con un file lungo in
tutto 3 righe.
Se invece dichiaro 
RecordInfo ri[192];
nessun errore...
Boh !! 
Stefano "HappyMan" (Lago Maggiore - NO)
--
Personal Web 
http://www.sgr.info
Email happyman69 (at) 
libero.it