zeiger auf zeiger aus einer struct
-
Hallo
Ich möchte eine dynamischen vector implementieren in c.
typedef struct { char **dynmem; size_t memlen; } DYNMEMVECTOR;
wie greiffe ich jetzt in der funktion xy die ein zeiger auf das struct bekommt zu? wenn ich zum bsp mit realloc dein soicherbereich vergrössern will?
int funcxy(DYNMEMVECTOR *dynmemptr)
{// so ?
*dynmemptr->dynmem = realloc(*dynmemptr->dynmem , lenx);...
...
-
-> bindet stärker als *. Das heißt
*dynmemptr->dynmem
bedeutet so viel wie*(dynmemptr->dynmem)
.Wieso ist das denn ein Doppelzeiger? Sollte das nicht nur ein einfacher Zeiger sein? Existiert
*dynmemptr->dynmem
überhaupt?
-
Es ist ein doppel zeiger da ich sonnst den Speicher ja nicht erweitern kann mit (realloc)... poste später mein realles bsp. ca. 1h. gruss
-
memuser schrieb:
Es ist ein doppel zeiger da ich sonnst den Speicher ja nicht erweitern kann mit (realloc)
realloc funktioniert anders.
-
int DynMemCat(DYNMEMVECTOR *ptrdynmem ,const char *srcmem ,size_t srclen ) { size_t currentlen = 0 ,srcstrlen = 0; char **mem = NULL; mem = &(ptrdynmem->ptrdynmem); if( srcmem == 0 ) return 0; if( *srcmem == 0 ) return 0; if( *mem == NULL ) { *mem = calloc(1 ,1); if(*mem == NULL) return 0; ptrdynmem->dynmemlen = 1; } *mem = realloc(*mem ,ptrdynmem->dynmemlen+srclen); if(*mem == NULL) return 0; memcpy(*mem+ptrdynmem->dynmemlen ,srcmem ,srcstrlen); ptrdynmem->dynmemlen += srclen; return 1; }
typedef struct { char **ptrdynmem; size_t dynmemlen; } DYNMEMVECTOR;
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "memlibc.h" int main(void) { DYNMEMVECTOR memptr = {0}; char str1[] = {66,66,0x65,0x65,0x65,0x65,0x65}; char str2[] = {0x02,0x02,0x02,0x02,0x02,0x02,0x02}; DynMemCat(&memptr ,str1 ,7); DynMemCat(&memptr ,str1 ,7); printf("%c",memptr.ptrdynmem); <- elemet 0 hat nicht 66 FreeDynMemCat(&memptr); getchar(); return 0; }
Bekomme falsche werte?
-
Warum sollte in
memptr.ptrdynmem
die 66 stehen?
memptr.ptrdynmem
ist ein char**. %c (bei printf) dient zur Ausgabe von char (int).
Großer Unterschied.
Das sagt mein Compiler dazu:
main.c|16|warning: format '%c' expects argument of type 'int', but argument 2 has type 'char **' [-Wformat]|char *z; // *z ist das char, z ist der Zeiger auf char char *zz; // **zz ist das char, *zz ist ein Zeiger auf char, zz ist ein Zeiger auf einen Zeiger auf char
Deine Funktion DynMemCat ist ein großes Zeigerdurcheinander.
int DynMemCat(DYNMEMVECTOR *ptrdynmem ,const char *srcmem ,size_t srclen ) { size_t currentlen = 0 ,srcstrlen = 0; char **mem = NULL; mem = &(ptrdynmem->ptrdynmem); //assignment from incompatible pointer type [enabled by default]| // &(ptrdynmem->ptrdynmem) ist die Adresse von ptrdynmem, nicht das worauf es zeigt. es ist ein char*** if( srcmem == 0 ) // Da wäre NULL verständlicher return 0; if( *srcmem == 0 ) // Das hat nur Sinn, wenn srcmem auf einen C-String zeigt return 0; // Tut es aber nicht, da die Nullterminierung fehlt. if( *mem == NULL ) { *mem = calloc(1 ,1); // Warum ? if(*mem == NULL) return 0; ptrdynmem->dynmemlen = 1; //?? } *mem = realloc(*mem ,ptrdynmem->dynmemlen+srclen); if(*mem == NULL) return 0; memcpy(*mem+ptrdynmem->dynmemlen ,srcmem ,srcstrlen); // selbst wenn das bis hier klappt, schreibst du die Zeichen durch das calloc erst ab Index 1 in den Speicher. // Auch deswegen kann da nicht die 66 stehen. ptrdynmem->dynmemlen += srclen; return 1; }
Und die Doppelzeiger (mem und ptrdynmem) sind hier total überflüssig.
Mach einfache Zeige daraus.
(Und vergiss nicht, den Wert von mem wieder in der struct abzulegen.)Lass das
calloc
weg.
realloc
verhält sich wiemalloc
, wenn der erste Parameter NULL ist.
-
Hallo
Danke DirkB jetzt habe ich es begriffen.
-
Hallo
Habe ich jetzt das so richtig verstanden?
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct { char **ptrdynmem; size_t dynmemlen; } DYNMEMVECTOR; int DynMemCat(DYNMEMVECTOR *ptrdynmem ,const char *srcmem ,size_t srclen ) { if( srcmem == 0 ) return 0; ptrdynmem->ptrdynmem = realloc(ptrdynmem->ptrdynmem ,ptrdynmem->dynmemlen+srclen); if(ptrdynmem->ptrdynmem == NULL) return 0; memcpy(ptrdynmem->ptrdynmem+ptrdynmem->dynmemlen ,srcmem ,srclen); ptrdynmem->dynmemlen += srclen; return 1; } void FreeDynMemCat(DYNMEMVECTOR *ptrdynmem) { free(ptrdynmem->ptrdynmem); return; } int main(void) { DYNMEMVECTOR memptr = {0}; char str1[] = {66,66,66,66,66,66,66}; char str2[] = {66,66,66,66,66,66,66}; DynMemCat(&memptr ,str1 ,7); DynMemCat(&memptr ,str2 ,7); printf("%c",memptr.ptrdynmem[0]); FreeDynMemCat(&memptr); getchar(); return 0; }
-
Nein! So wäre es richtig...
typedef struct { char *ptrdynmem; // Einfacher char zeiger size_t dynmemlen; } DYNMEMVECTOR; int DynMemCat(DYNMEMVECTOR *ptrdynmem ,const char *srcmem ,size_t srclen ) { if( srcmem == 0 ) return 0; ptrdynmem->ptrdynmem = realloc(ptrdynmem->ptrdynmem ,ptrdynmem->dynmemlen+srclen); if(*ptrdynmem->ptrdynmem == NULL) return 0; memcpy(ptrdynmem->ptrdynmem+ptrdynmem->dynmemlen ,srcmem ,srclen); ptrdynmem->dynmemlen += srclen; return 1; } void FreeDynMemCat(DYNMEMVECTOR *ptrdynmem) { free(ptrdynmem->ptrdynmem); return; } int main(void) { DYNMEMVECTOR memptr = {0}; char str1[] = {66,66,66,66,66,66,66}; char str2[] = {66,66,66,66,66,66,66,0}; // zur Demo DynMemCat(&memptr ,str1 ,7); DynMemCat(&memptr ,str2 ,8); printf("%s",memptr.ptrdynmem); // und so greifst du auf den Speicher zu. Funktioniert hier mit %s weil str2 am ende eine 0 Terminierung hat. FreeDynMemCat(&memptr); getchar(); return 0; }
-
memuser schrieb:
typedef struct { char **ptrdynmem; size_t dynmemlen; } DYNMEMVECTOR; ... printf("%c",memptr.ptrdynmem[0]);
So war es gemeint. Beim zz ist der zweite * abhanden gekommen
char *z; // *z ist das char, z ist der Zeiger auf char char **zz; // **zz ist das char, *zz ist ein Zeiger auf char, zz ist ein Zeiger auf einen Zeiger auf char
Ein Arrayzugriff ersetzt einen *
Also istchar **zz; // zz[0][0] ist das char, zz[0] ist ein Zeiger auf char, zz ist ein Zeiger auf einen Zeiger auf char
memptr.ptrdynmem[0] ist bei dir daher immer noch ein
char*
und keinchar
Die Variable mem war aber nicht so verkehrt.
Das gilt für die Version von -lowbyte- (mit einfachem Zeiger):int DynMemCat(DYNMEMVECTOR *ptrdynmem ,const char *srcmem ,size_t srclen ) { char *mem = ptrdynmem->ptrdynmem; if( srcmem == NULL ) return 0; mem = realloc(ptrdynmem->ptrdynmem ,ptrdynmem->dynmemlen+srclen); if(mem == NULL) return 0; // so bleibt im Fehlerfall noch alles beim alten ptrdynmem->ptrdynmem = mem; memcpy(ptrdynmem->ptrdynmem+ptrdynmem->dynmemlen ,srcmem ,srclen); ptrdynmem->dynmemlen += srclen; return 1; }
Und mit einfachem Zeiger für ptrdynmem, klappt auch
printf("%c",memptr.ptrdynmem[0]);
-
Das alles stimmt aber nur für die Annahme, dass der Frager mit "Vektor" eine Folge von Zeichen/Bytes meint und nicht eine Folge von Zeichenketten/Bytearrays.
Bei Letzterem wäre dann char** OK.