Was mache ich falsch mit den Pointern?
-
Hallo zusammen,
ich brauch nochmal eure hilfe. mein problem: ich habe ein zielfeld in welches ich bits reinschreiben will. dann hab ich ein value, welcher vom typ uint8, uint16, uint32, ... ist, von diesen muß ich aber evtl. nur 3 oder 4 bit rüberkopieren. die werte sollen geschlossen hintereinander stehen. bsp:
uint8[3] ziel={0,0,0}; void* p_ziel = &ziel[0]; uint16 value = 3; p_ziel = add_num(p_ziel,value,2,sizeof(uint16)); //ziel[0]--> 192 add_num(p_ziel,value,2,sizeof(uint16)); //ziel[0] --> 240
im moment versuche ich es so:
void* add_num (uint8_t** dest, void *what, size_t cnt, size_t** startPos) { uint8_t bit_offset = **startPos-1; for(;cnt>0;cnt--, bit_offset--){ printf(" cnt: %i bit_pos: %i value: %i\n",cnt, bit_offset, (*(uint8_t*)what & (1<<(cnt-1))?1:0)); //what+byte //1<<bitIndex if(*(uint8_t*) what & (1<<(cnt-1))){ **dest |= (1 << bit_offset); //where }//End if if(bit_offset == 0){ bit_offset = 8; *(*dest++); }//End if }//End for **startPos = bit_offset; }//End add_num #define simpleUpdateCodeLength DSMQL_SET_CONDITION_ENCODE_LENGTH +DSMQL_VAR_BIT_ENCODE_LENGTH +(varMappingTable[data->var_id][1]) void encodeSimpleUpdate(data_t* data, uint8_t* result, uint8_t* length){ uint8_t val = 255; uint8_t dest[(simpleUpdateCodeLength&7?1:0)+(simpleUpdateCodeLength>>3)]; uint8_t* p_dest = &dest[0]; uint8_t** pp_dest = &p_dest; size_t start = 3; size_t* start_pos = &start; size_t** pos = &start_pos; memset(&dest,0,(*length)*8); add_num(pp_dest, &val, 8, pos); printf("[0]: %i\n",dest[0]); printf("[1]: %i\n",dest[1]); printf("[2]: %i\n",dest[2]); add_num(pp_dest, &val, 8, pos); printf("[0]: %i\n",dest[0]); printf("[1]: %i\n",dest[1]); printf("[2]: %i\n",dest[2]); }
An der Stelle:
if(bit_offset == 0){ bit_offset = 8; *(*dest++); }//End if
bricht er mit einem pointer fehler ab. jemand einen tip?? mfg
-
also ohne mich durch dieses zeigerwirrwarr gewunden zu haben
was willst du denn mit*(*dest++);
auch erreichen? du inkrementierst den dereferenzierten zeiger um 1. soweit ok. aber warum dereferenzierst du ihn dann nochmals? dass kann für den compiler keinen sinn ergeben.
-
uwerothfeld schrieb:
...mein problem: ich habe ein zielfeld in welches ich bits reinschreiben will. dann hab ich ein value, welcher vom typ uint8, uint16, uint32, ... ist, von diesen muß ich aber evtl. nur 3 oder 4 bit rüberkopieren. die werte sollen geschlossen hintereinander stehen...
vielleicht hilft dir das:
#define setbit(arr,pos) ((arr)[(pos)>>3]|=(1<<(7-((pos)&7)))) #define getbit(arr,pos) ((arr)[(pos)>>3]&(1<<(7-((pos)&7)))) void bitcopy_lame (unsigned char *src, // zeigt auf das quellarray unsigned char *dest, // zeigt auf das zielarray size_t begin_src, // startbit im quellarray size_t begin_dest, // startbit im zielarray size_t length) // anzahl zu kopierender bits { while (length) { if (getbit(src, begin_src)) setbit (dest, begin_dest); begin_src++; begin_dest++; length--; } }
das ist sozusagen die primitivlösung eines memcpy auf bitebene. damit kannst du eine beliebige anzahl von bits von irgendwo nach sonstwo kopieren. ziel und quelle müssen als 'unsigned char*' übergeben werden.
ist zwar alles sehr unperformant, aber sollte funktionieren.
-
edit: ^^
das zielarray muss komplett leer sein, sonst bräuchte die funktion im else-zweig ein 'clearbit'-makro. hier mal die ausgebesserte version#define setbit(arr,pos) ((arr)[(pos)>>3]|=(1<<(7-((pos)&7)))) #define clearbit(arr,pos) ((arr)[(pos)>>3]&=~(1<<(7-((pos)&7)))) #define getbit(arr,pos) ((arr)[(pos)>>3]&(1<<(7-((pos)&7)))) void bitcopy_lame (unsigned char *src, // zeigt auf das quellarray unsigned char *dest, // zeigt auf das zielarray size_t begin_src, // startbit im quellarray size_t begin_dest, // startbit im zielarray size_t length) // anzahl zu kopierender bits { while (length) { if (getbit(src, begin_src)) setbit (dest, begin_dest); else clearbit (dest, begin_dest); begin_src++; begin_dest++; length--; } }
-
Hallo,
erst mal danke für eure antworten, der code macht fast das was ich will. nur an der angegeben stelle springt er raus. hier vielleicht nochmal zur verdeutlichung was ich tun will:
Der PointerPoint dest zeigt auf einen Pointer welcher ein Feld ist:
dest --> p_ziel --> ziel[3]
letztlich will ich in das ziel schreiben, ab einen bestimmten feldindex und einen bestimmten bitindex. also schreib:
feldindex 0 feldindex 1 feldindex 3 .... ziel: [_|_|_|_|_|_|_|_] [_|_|_|_|_|_|_|_] [_|_|_|_|_|_|_|_] ... ^ ab hier die nächsten x bit
die stelle
if(bit_offset == 0){ bit_offset = 8; *(*dest++); }//End if
behandelt nun gerade den wechsel von feldindex 0 zu feldindex 1, soll also die bitindexe neu setzen. als ergebnis will ich zum beispiel sowas haben:
feldindex 0 feldindex 1 feldindex 3 .... ziel: [_|_|_|_|_|1|1|1] [0|1|1|1|_|_|_|_] [_|_|_|_|_|_|_|_] ... ^
die letzte pos und den dest auf der aktuellen feldindex will ich zurück, über die eingabe, daher **dest.
jemand einen tip was ich falsch mach?
-
hallo,
ach ich habs!!!
es lag einfach an:
(*dest)++;
dann noch die werte für bit_offset und startPos korrigiert und es geht!!!
die ** pointer verwende ich, da ich so nicht weiter rechnen muß wo ich bin, sondern die werte für die bitposition und feldindex immer die richtige werte beinhalten.
ich danke euch, manchmal muß man halt nur einen fremden trauf schauen lassen und man findet das problem. sehr schön. an alle, vielen dank.
ghostdog