für was brauch ich dynamische Speicherverwaltung??



  • also ich hatte schon lange, bis ich herausgefunden habe, für was Pointer zu gebrauchen sind, aber für was brauch ich dynamische Speicherverwaltung??
    Ich versteh zwar, wie das geht (malloc und co..), aber was bringt mir das?
    Ist es schneller, als wenn ich "normale" statische Variablen benütze?

    gruss

    nightmare_frog



  • damit du z.b. ein feld anlegen kannst, dessen größe erst zur laufzeit bekannt ist/wird



  • Original erstellt von nightmare_frog:
    **also ich hatte schon lange, bis ich herausgefunden habe, für was Pointer zu gebrauchen sind, aber für was brauch ich dynamische Speicherverwaltung??
    Ich versteh zwar, wie das geht (malloc und co..), aber was bringt mir das?
    Ist es schneller, als wenn ich "normale" statische Variablen benütze?
    **

    es ist langsamer

    kleine aufgabe:
    schreibe mir bitte eine string 'klasse'

    ich will sie so benützen können:

    struct string str;
    set_value(&str,"Hallo Welt");
    printf("%s",get_value(&str));



  • Die dynamische Speicherverwaltung wird dann interessant wenn du ein Programm schreibst indem immer wieder neue Daten eingegeben werden, diese auch erhalten bleiben sollen und sich die Daten auch oft ändern können. Ein gutes Beispiel ist ein Programm mit dem man einen Bücherbestand verwalten kann. Der Programmierer kann zum Zeitpunkt des codens nicht wissen wieviele Bücher eingegeben werden und da ist es schon sinnvoll dynamische Speicherverwaltung zu wählen, da dann der user soviele Daten eingeben kann wie er will bzw. bis der Speicher (Heap) des Rechners zu ist.



  • bei get_value(&str) hakt es. hast du die aufgabe extra so fies geschrieben?



  • danke für die Antworten, jetzt kapier ich, für was man das brauchen kann...

    @Shade Of Mine: ich werds mal versuchen...

    @nightmare_frog: du hast meinen Nick geklaut 😡 😮 😉



  • ups, muss wohl ein zufall gewesen sein. hab exakt den gleichen nickname, bin aber meines wissen länger im board vertreten als du. 😮

    hoppla, ich habe vergessen zu schreiben, was für eine Ufo-Sekte ich meine, ich meine die Rael-Sekte...

    gruss

    nightmare_frog



  • const char * getvalue(const struct string * str) {
      return str->value;
    }
    

    Das ist doch der einfachere Teil. ITIHBT 🤡



  • I think I have been trolled? 😕 😕



  • @nightmare_frog: dann gibt es halt jetzt 2 von uns :D.

    @Shade Of Mine: also die erste Funktion krieg ich nicht hin, aber die zweite schon... (Habs allerdings noch nicht mit dynamischer Speicherverwaltung versucht...)

    gruss

    nightmare_frog



  • Original erstellt von nightmare_frog:
    **@Shade Of Mine: also die erste Funktion krieg ich nicht hin, aber die zweite schon... (Habs allerdings noch nicht mit dynamischer Speicherverwaltung versucht...)
    **

    probiers mal mit malloc 🙂

    um das free() musst du dich noch nicht sorgen, das kannst du dann nachher machen -> stichwort Konstruktor/Destruktor



  • ich habs geschaft :), allerdings ohne dynamische Speicherverwaltung 🕶

    @Shade Of Mine: kannst du mir noch die Lösung mit malloc() zeigen? Ich habs auch versucht, aber nicht geschafft...

    #include <stdio.h>
    #include <string.h>

    struct string_struktur
    {
    char text[100];
    }str;

    void set_value(struct string_struktur *ausgabe,char string[100])
    {
    strcpy(ausgabe->text,string);
    }

    char *get_value(struct string_struktur *eingabe)
    {
    return eingabe->text;
    }

    int main()
    {
    set_value(&str,"Hallo Welt\n");
    printf("%s",get_value(&str));

    system("PAUSE");

    return 0;
    }

    gruss

    nightmare_frog



  • der string und somit die speichernutzung soll aber unbekannte, bzw. adaptive grösse haben.
    bei nem 150 byte langen string macht dein prog nicht mehr mit.



  • typedef struct string
    {
    char* value;
    };
    
    void set_value(string* str, char* p)
    {
       str->value=realloc(str->value,strlen(p)+1);
       strcpy(str->value,p);
    }
    
    const char* get_value(string* str)
    {
      return str->value;
    }
    

    deine aufgabe könnte jetzt daraus bestehen, set_value zu optimieren... und vorallemfehler abzufangen.
    dann könntest du dich dran setzen und auch eine delete_value funktion schreiben, die den speicher wieder frei gibt.
    vielleicht auch noch eine funktion get_value_at() welche den char an stelle x zurück gibt.

    ich denke das ist eine gute übung für dynamische speicherverwaltung und vorallem für zeiger

    nicht vergessen: alles absturz sicher machen

    [ Dieser Beitrag wurde am 06.02.2003 um 12:15 Uhr von Shade Of Mine editiert. ]



  • und es funktioniert sogar 😃 ..
    danke für die Lösung, versuche mal die anderen Funktionen zu programmieren..

    gruss

    nightmare_frog



  • Original erstellt von nightmare_frog:
    **und es funktioniert sogar 😃 ..
    **

    achtung.
    set_value hat mindestens ein höllisches problem.
    versuch es zu finden und schau dir dazu die funktion realloc mal an.

    um genau zu sein: im realloc aufruf stecken 2 fehler.
    einer ist höllisch und wird dir in der release version um die ohren fliegen, der andere muss nicht zum vorschein kommen (genauer gesagt es ist unwahrscheinlich dass er auftritt, kann aber auch mal passieren)

    weiters ist die performance unter aller sau - also da kannst du noch ne menge machen 🙂



  • so, ich habs mal versucht...
    aber wieso hast du realloc und nicht calloc genommen? ich habe zwar nicht herausgefunden, wieso es mit realloc() ein Problem geben sollte in diesem Programm, aber ich könnte mir vorstellen, dass es daran liegt, dass realloc einen reservierten Speicherplatz erweitert und wenn ja beim ersten Aufruf noch kein Speicherplatz reserviert wurde, könnte das zu Problemen führen...
    hier ist mein Code (allerdings funktioniert das mit den free()-Funktionen nicht richtig, wenn die Eingabe länger als eine Zeile ist, gibt es einen Absturz...), was kann man da noch optimieren?(ausser alle Funktionen aufzulösen):

    #include <stdio.h>
    #include <string.h>
    
    typedef struct string_struktur
        {
            char *text;
        }STR;
    
    STR str;
    STR *ausgabe;
    STR *eingabe;
    
    void pause()
    {
        system("PAUSE");
    }
    
    void set_value(STR *eingabe,char *string)
    {
        strcpy(eingabe->text=calloc(eingabe->text,strlen(string)+1),string);
    }    
    
    char *get_value(STR *ausgabe)
    {
        return ausgabe->text;
    }
    
    char *get_value_at(STR *ausgabe,int *pos)
    {
    int position = *pos;
        return ausgabe->text[--position];
    }
    
    void del_value()
    {
        free(str);
    }
    
    int main()
    {
    int *pos;
    int ende = 0;
    char *value;
    
        while(ende==0)
        {
        atexit(pause);
        printf("Text eingeben (0 fuer Ende): ");
        fflush(stdin);
        gets(value=(char *)malloc(sizeof(*value)));
        fflush(stdin);
        if(!strcmp(value,"0"))
            exit(0);
        printf("Position eingeben: ");
        scanf("%i",pos=(int *)malloc(sizeof(*pos)));
        fflush(stdin);
    
        if(*pos>strlen(value))
        {
            printf("\nZu hohe Position\n");
            exit(0);
        }
    
        set_value(&str,value);
        printf("\nDas %ite Zeichen von %s ist %c\n\n",*pos,get_value(&str),get_value_at(&str,pos));
        del_value();
        free(pos);
        free(value);
        }
    
     return 0;
    }
    

    danke für die hilfe 🙂

    gruss

    nightmare_frog

    [ Dieser Beitrag wurde am 06.02.2003 um 16:52 Uhr von nightmare_frog editiert. ]

    [ Dieser Beitrag wurde am 06.02.2003 um 16:54 Uhr von nightmare_frog editiert. ]



  • Nein so nicht. Das Programm hat gravierende Fehler, von Stilfehlern wie globalen Variablen mal abgesehen. Einen greif ich mal exemplarisch heraus, weil er so schön ist:

    gets(value=(char *)malloc(sizeof(*value)));
    

    Erklär doch mal, was du mit der Zeile bezwecken willst.

    Ich sag dir was sie in wirklichkeit tut: Sie reserviert 1 Byte per malloc (sizeof *value == sizeof(char) == 1), und läßt den User dann ab diesem Byte beliebigen Text in den Speicher schreiben. Da stdlib.h nicht eingebunden ist, geht der Compiler aufgrund eines fehlenden Prototypen davon aus, dass malloc als int malloc(...) definiert ist. Eine entsprechende Warnung schaltest du durch einen Cast int -> char* explizit aus (noch mehr undefiniertes Verhalten).



  • hoppla 😕 ...
    also mit dieser Zeile wollte ich, dass der Speicherbereich für die Variable je nach eingabe angepasst wird, wie soll man das anders lösen???

    na ja, da merkt man, dass ich doch nicht so viel ahnung von dynamischer speicherverwaltung habe, wie ich gedacht habe 😞 ...
    Ich habe mal die stdlib.h eingebunden, jetzt gehts :).
    es ist ja nur ein Übungs-Programm, und ich finde es übersichtlicher, wenn die Struktur global ist...



  • es geht? Glück gehabt, dir könnten auch Dämonen aus der Nase fliegen ...

    gets zu verwenden ist eigentlich ganz einfach, es gibt nur eine einzige Regel:
    1. Benutze nie gets.

    Zu deinem Problem: Es ist nicht ohne weiteres (sprich: durch einen einfachen Aufruf einer Standardfunktion) möglich, eine Eingabe in einen sich selbst anpassenden Puffer zu leiten. GNU hat eine getline Funktion, die das kann (nicht zu verwechseln mit std::getline von C++). Ansonsten bleibt nur fgets, womit man immerhin die Größe des Puffers angeben kann, so dass der User keinen Überlauf produzieren kann, und irgendwas mit realloc und getchar zu zaubern.



  • Original erstellt von nightmare_frog:
    **[...]while(ende==0)
    {
    atexit(pause);
    printf("Text eingeben (0 fuer Ende): ");
    fflush(stdin);
    gets(value=(char *)malloc(sizeof(*value)));
    fflush(stdin);
    if(!strcmp(value,"0"))
    exit(0);
    printf("Position eingeben: ");
    scanf("%i",pos=(int )malloc(sizeof(pos)));
    fflush(stdin);
    [...]

    fflush( stdin );
    

    erzeugt ein undefiniertes Verhalten -> aus der FAQ 🙂


Anmelden zum Antworten