sizeof () zeigt alloziierten Speicher nicht an!?



  • Hallo Helfer,
    ich möchte einen einzugebenden String in einem größeangepassten Array speichern!

    a)Ich komme immer nur auf Lösungen in denen ich die Eingabe zunächst doch immer erst in einem statischen Array zwischenspeichern muss. Aber meine folgendes Programm hat auch noch den Fehler, dass es den alloziierten Speicher nicht anzeigt:

    int main(void)
    {	
    	char c;
    	char Grundeingabe [100]={0}; //festes Array als Zwischenspeicher
    	char* Ausgangsstring; //Eigentlicher Speicher für meine Eingabe
    	printf ("Bitte einen Ausgangsstring angeben:\t");
    	fgets(Grundeingabe,sizeof(Grundeingabe),stdin); //Mit Newline-zeichen
    
    	Ausgangsstring = (char *)malloc (strlen(Grundeingabe)+1); //Mit 1 addieren, da strlen das Nullbyte nicht miteinliest
    	strcpy(Ausgangsstring,Grundeingabe);
    	printf ("%s bei einer Laenge von %d",Ausgangsstring, sizeof (Ausgangsstring)); //Ausgabe meiner Eingabe und des Wertes 4
    
    	fflush (stdin);
    	getchar();//Warten lassen
    	return 0;
    }
    

    Es zeigt den String immer richtig aus Ausgangsstring herraus an, gibt dessen grösse aber IMMER mit 4byte an! 😕

    b)Ist die Lösung aus dem Tread Dynamischer String in C vom 08.06.09 eine elegante? Und kann man so akzeptabel einen Zwischenspeicher-Array umgehen?



  • 1. Den Rückgabewert von malloc nicht casten.

    2. sizeof gibt die Größe des Ausdrucks zurück. Bei einem Pointer also die Größe des Pointers(!) und nicht des Speicherbereichs auf den der Pointer zeigt! Es gibt keinen (portablen) Weg die Größe zu ermitteln.

    zu b: Wie wäre es mit einem Link...



  • Normalerweise merkt man sich die Größe des dynamischen Arrays in einer Variable (schließlich hat man die selbst angegeben) und schleppt die einfach mit. Dann braucht man auch kein 'Zwischenspeicher-Array'...



  • Danke schon mal für die Antworten.

    zu b: Wie wäre es mit einem Link...

    Das ist natürlich eine großartige Idee 👍 🙄
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-242705.html

    Das mit dem Casten von Malloc ist auch in dem Artikel ein Gesprächsthema. Da werde ich mich mal der klugen Masse anschliesen und demnächst die Finger Davon lassen.

    Zu Matze: Ich glaube du hast mich falsch verstanden. Ich brauche das Zwischenspeicherarray nicht um mir die Grösse zu merken, sonder um die unbekannt lange Eingabe ersteinmal Zwischenzulagern, damit ich dann deren Länge ermitteln kann und dann nur den wirklich benötigten Speicherplatz alloziieren (<--ich liebe dieses Wort) muss.
    Das mit der grösse kann man ja anscheinend nicht vernünftig rauskriegen ausser mit dem eigenen Menschenverstand.

    Es gibt keinen (portablen) Weg die Größe zu ermitteln.

    Ich finde da geht ein bisschen Kontrolle verloren! 😞



  • Balu Jr. schrieb:

    Danke schon mal für die Antworten.

    zu b: Wie wäre es mit einem Link...

    Das ist natürlich eine großartige Idee 👍 🙄
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-242705.html

    Hab dort geantwortet…

    Es gibt keinen (portablen) Weg die Größe zu ermitteln.

    Ich finde da geht ein bisschen Kontrolle verloren! 😞

    Ja, vor allem muss sich die Umgebung die Größe ja eh merken.



  • benötigten Speicherplatz alloziieren (<--ich liebe dieses Wort) muss.

    Gibts das Wort überhaupt heist es nich einfach Allokieren??? 😋



  • mach das Allokierungsfunktionen!!!

    struct YourString
    {
    char* string;
    int len;
    }
    
    struct YourString AllocStrMem(char* scr)
    {
      struct YourStruct tmp;
    
    tmp.len = strlen(scr);
    tmp.string=malloc (tmp.len+1);
    tmp.string[tmp.len]= '\x0';
    tmp.len = strlen(scr);
    
    return tmp;
    }
    

    SO irgendwie........



  • mach das Allokierungsfunktionen!!!

    Dann mach aber auch eine free Funktion...



  • Korrekt Theta:

    void FreeStrMem(struct YourString scr)
    {
     if(scr !=null && scr.string!=null)
        free(scr.string);
      scr.len=0;
    
     }
    

    hier chef...



  • 1. Statt:

    Jihhaaa schrieb:

    tmp.string[tmp.len]= '\x0';
    

    das hier:

    strcpy(tmp.string, scr);
    

    2. muss natürlich trotzdem irgendwo bereits allokierter Speicher vorhanden sein, der scr beherbergt.



  • stimmt hab vergessen den string zu kopieren.. aber immerhin Null terminiert^^



  • Gibts das Wort überhaupt heist es nich einfach Allokieren???

    Also ich habe im Duden nachgeschaut: Das Wort allozieren gibt es wirklich, aber natürlich mit nur einem 'i'. Es heist übersetzt "belegen,reservieren";
    Das Wort allokieren gibt es aber auch und heist eher "ansprechen";
    Hier ist es auch ganz gut erklärt: http://faql.de/fremdwort.html

    Jihhhaaa, danke für deine Funktionen, aber damit hast du doch im Prinzip die normalen Funktionen "nur" anders verpackt und das löst das Problem ohne Zwischenspeicher an ein dynamisch angepasstes Array zu kommen eher nicht. Ich könnte ja eigentlich mit den original Stringfunktionen arbeiten.

    Also kann man nicht um ein Zwischenspeichern rum kommen!????



  • Ja, allozieren und allokieren werden beide in dem Kontext verwendet. Kommt immer auf's Buch oder den Gesprächspartner an...

    EDIT: Zum Thema Zwischenspeicher-String. Du könntest natürlich zeichenweise einlesen und dein dynamisches Array schrittweise reallozieren (z.B. immer in 10er-Schritten vergrößern). Umständlich, aber so stellst du sicher, dass nicht zuviel Platz verschwendet wird, aber auch nicht zu wenig bereitgestellt wird. Was passiert denn beispielsweise bei deiner Variante, wenn der User mehr als 99 Zeichen eingibt?



  • Balu Jr. schrieb:

    Also kann man nicht um ein Zwischenspeichern rum kommen!????

    Doch, man kann, guckst du hier:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-242705-and-start-is-10.html

    Auf Minimalsystemen kann BUFSIZ zu groß werden und ein malloc versagt.

    Meiner Meinung nach wird um das zeichenweise reallozieren zu viel Wirbel gemacht. Handelt es sich um eine Benutzereingabe, so macht der Prozessor auch bei einem realloc pro Zeichen die meiste Zeit über nix anderes als Nix, er wartet also auf die Eingabe.

    Guckst du hier für dynamischen String ohne BUFSIZ und ohne Zwischenpuffer:

    char* coninput2()
    {
    	int c = 0, i = 1;
    	char* s = NULL, *t = NULL;
    
    	while ( (c = fgetc(stdin)) != '\n' && c != EOF )
    	{
    		if( NULL == (t = realloc(s, i+1)))
    			break;
    		s = t;
    		s[i-1] = c;
    		s[i++] = 0;
    	}
    	return s;
    }
    

    Für gewöhnliche PC Programme mit ausreichend Arbeitsspeicher würde ich aber die Mr. C Variante nehmen.
    Gruß,
    B.B.



  • Was passiert denn beispielsweise bei deiner Variante, wenn der User mehr als 99 Zeichen eingibt?

    ICh weiss Matze. Dann gibts nen schönen Bufferoverflow. Aber desshalb habe mache ich ja auch hier gefragt. Das meine ich mit dem statischen Array. Das müsste ja sonst unendlich groß sein und das ist/war eben mein Problem.

    Doch, man kann, guckst du hier:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-242705-and-start-is-10.html

    Danke für den Hinweis, aber guck mal wer da auch seine Finger schon mit im Spiel hat.... ich.
    Da das ein ähnliches Problem ist, hab ich da auch gepostet!



  • Big Brother schrieb:

    Meiner Meinung nach wird um das zeichenweise reallozieren zu viel Wirbel gemacht. Handelt es sich um eine Benutzereingabe, so macht der Prozessor auch bei einem realloc pro Zeichen die meiste Zeit über nix anderes als Nix, er wartet also auf die Eingabe.

    bei benutzereingaben u.ä. langsamen datenquellen (und wenn die CPU sonst nix zu tun hat) mag es egal sein. aber bedenke, dass du nach der methode 'pro byte' übelst viel rechenzeit verballerst. erst recht, wenn realloc mal seine listen umsortiert.
    🙂


Anmelden zum Antworten