/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
memcpy
Fra : Andreas Andersen


Dato : 17-11-02 09:39

Jeg har en char pointer og vil gerne kunne hente 1, 2 og 4 bytes fra
denne og kaste dem til int. Det jeg prøver er:

char* instr;
int ip = 0;
//hent fil ind og malloc instr

unsigned int readBytes(int number) {
unsigned int *theResult;
memcpy(theResult, (instr + ip), number);
ip += number;
return *theResult
}

Det virker fint, hvis number=1 eller 2, men hvis det er 4 går programmet
   
ned med lagersegmenteringsfejl engang imellem. Det er ikke fordi jeg
prøver at læse over enden af instr. Hvad kan der være galt??

På forhånd tak
Andreas


 
 
Peter dfoe (17-11-2002)
Kommentar
Fra : Peter dfoe


Dato : 17-11-02 09:57

> unsigned int readBytes(int number) {
> unsigned int *theResult;
> memcpy(theResult, (instr + ip), number);
> ip += number;
> return *theResult
> }
>
> Det virker fint, hvis number=1 eller 2, men hvis det er 4 går programmet

theResult er en pointer til en int, men er ikke en int som sådan..kun en
pointer.
Prøv unsigned int *theResult=new unsigned long int;





Jesper Toft (17-11-2002)
Kommentar
Fra : Jesper Toft


Dato : 17-11-02 10:48

Andreas Andersen wrote:

> Jeg har en char pointer og vil gerne kunne hente 1, 2 og 4 bytes fra
> denne og kaste dem til int. Det jeg prøver er:
>
> char* instr;
> int ip = 0;
> //hent fil ind og malloc instr
>
> unsigned int readBytes(int number) {
> unsigned int *theResult;
> memcpy(theResult, (instr + ip), number);
> ip += number;
> return *theResult
> }
>
> Det virker fint, hvis number=1 eller 2, men hvis det er 4 går programmet
>
> ned med lagersegmenteringsfejl engang imellem. Det er ikke fordi jeg
> prøver at læse over enden af instr. Hvad kan der være galt??

Du læser til noget uinitialiseret hukommelse. theResult er en pointer, der
peger på hvad end der stod på hukommelses pladsen i forvejen.

Hvis number er max=4, så prøv flg:

unsigned int readBytes(int number) {
unsigned int theResult=0;
memcpy(&theResult, (instr + ip), number);
ip += number;
return theResult
}

Memcpy til theResult. & tegnet gør at memcpy får en pointer til din variabel
istedet for variablen selv.

/Jesper Toft


Klaus Petersen (18-11-2002)
Kommentar
Fra : Klaus Petersen


Dato : 18-11-02 13:08

unsigned int readBytes(int number) {
unsigned int *theResult;
memcpy(theResult, (instr + ip), number);
ip += number;
return *theResult
}

Din funktion er lidt mærkelig. For det første er det underligt, at du sender
et tal ind som et parameter, som angvier det antal bytes der skal læses.
Hvad skal du bruge det til, når størrelse af en "unsigned int" altid er 4?

Du kopierer også fra en buffer, som tilsyneladende er erklæret globalt -
hvorfor så lave en funktion til det?

Din sourcepointer tvivler jeg på er gyldig og da slet ikke din
destinationspointer.

Efter min mening burde funktionen se nogenlunde sådan ud:

unsigned int readUInt32 ( char *Buffer, DWORD &offset )
{
unsigned int temp;
memset ( &temp, &Buffer [offset], sizeof (unsigned int) );
offset += sizeof (unsigned int);
return temp;
};

og kaldet til det vil komme til at se nogenlunde sådan ud:

// eksempel på erklæringer:
// char InStr [256];
// DWORD lp = 0;
// unsigned int min_uint;
min_uint = readUInt32 ( (char*)&InStr, lp );

Her efter vil lp være 4 og min_uint vil indeholde hvad end der var i
bufferen.




Andreas Andersen (18-11-2002)
Kommentar
Fra : Andreas Andersen


Dato : 18-11-02 14:53

> Din funktion er lidt mærkelig. For det første er det underligt, at du
sender
> et tal ind som et parameter, som angvier det antal bytes der skal læses.
> Hvad skal du bruge det til, når størrelse af en "unsigned int" altid er 4?
Jeg skal jo vide hvor mange bytes jeg skal læse fra instr hvis instr f.eks.
er 02 DA CE 15
og jeg skriver readBytes(2) får jeg 02DA tilbage og ikke 02DACE15

> Du kopierer også fra en buffer, som tilsyneladende er erklæret globalt -
> hvorfor så lave en funktion til det?
Jeg synes bare det er pænere med readBytes(2) end memcpy(...) ip += 2 - det
står overalt i min kode. Det kan selvfølgelig være jeg burde lave en makro
istedet....

Jeg har i øvrigt fået det til at virke med Jesper Tofts løsning.

MvH
Andreas



Richard Flamsholt (18-11-2002)
Kommentar
Fra : Richard Flamsholt


Dato : 18-11-02 20:49

"Andreas Andersen" <andreasa@daimi.au.dk> skrev:
>Jeg har i øvrigt fået det til at virke med Jesper Tofts løsning.

Den virker kun, fordi du er heldig. Og med daimi i adressen er det ikke
godt at forlade sig på held.

>hvis instr f.eks. er 02 DA CE 15
>og jeg skriver readBytes(2) får jeg 02DA tilbage og ikke 02DACE15

> unsigned int theResult=0;
> memcpy(&theResult, (instr + ip), number);

Hvis sizeof(unsigned int)==4 ender theResult med dette bitmønster:

   02 DA 00 00

På en little-endian CPU, som Intels x86, fortolkes det som 0xDA02 (og
ikke 0x02DA, som du skrev, men det er nu en detalje). Men en big-endian
processor vil fortolke det som 0xDA020000, så din metode vil returnere
et meget stort og forkert tal.

Big-endian CPU'er er fx Motorola 680x0, PowerPC og Sparc, så på en Mac
eller en Sun ville programmet opføre sig fejlagtigt. Network byte-order
(dvs den måde internet-protokoller overfører data på) er svjh ligeledes
big-endian.

Løsningen er 1) at klarlægge formatet af data og derefter 2) eksplicit
læse/skrive i det format. Fx ville en skudsikker måde (håber jeg; det er
off the top of my head og utestet og længe siden jeg sidst har C'et) at
læse 2 bytes little-endian data på, være:

   theResult = (unsigned int)instp[0] + ((unsigned int)instp[1]<<8)

mvh Richard
--
Richard Flamsholt
richard@flamsholt.dk - www.richard.flamsholt.dk

Søg
Reklame
Statistik
Spørgsmål : 177500
Tips : 31968
Nyheder : 719565
Indlæg : 6408509
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste