C - Dynamische Speicherverwaltung

Neue Frage »

Auf diesen Beitrag antworten »
InformaTiger C - Dynamische Speicherverwaltung

Guten Abend,

ich sitze derzeit bei einem Programm, welches mittels dynamischer Speicherverwaltung einen String vergrößern und Zeichen anfügen soll. Das Programm sieht wie folgt aus:

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void str_append(char **target, char character);
void str_reverse(char **target);

int main()
{
    char * str = malloc(1);
    //strcpy(str, "0");
    
    for (int i = 256; i > 0; i /= 2){
        char digit = (i % 2) + '0';
        str_append(&str, digit);
    }
    str_reverse(&str);
    
    printf("%s\n", str);
    free(str);
    
    return EXIT_SUCCESS;
}


Im Fall dass die Zeile mit dem strcpy(str, "0") auskommentiert ist, erhalten ich einen Segmentation fault. Welcher Schritt fehlt, dass die Variable, welche ich über malloc() angelegt habe, verwendet werden kann?

smile

Edit: Habe den Fehler gefunden! großes Grinsen er lag an dem Code, den man hier nicht sehen kann. Zunächst habe ich nur in einer Online-Konsole entwickelt und den Fehler "segmentation fault" bekommen; als ich dann auf die IDE gewechselt bin wurde er mit "pointer being realloc'd was not allocated" schon etwas genauer. Folgend die Methode die den Fehler enthielt und die if-Anweisung die gefehlt hat smile

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
void str_append(char **target, char character){
    char * value = *target;
    int length = strlen(value);

    if (length != 0){ // <-- hier lag der Fehler
        value = realloc(*target, length * sizeof(char));
    }
    value[length] = character;
}


Mit freundlichen Grüßen
InformaTiger
 
Auf diesen Beitrag antworten »
Karlito

Hallo Informatiger,

Du hast einen typischen Anfängerfehler in C gemacht. "0" ist zwei Zeichen lang! Das liegt daran, dass ein String immer mit '\0' abgeschlossen werden muss, wohl gemerkt nicht '0'. Wenn Du den String mit "" angibst wird das implizit mit gemacht. Ein String ist in C nichts anderes als ein Char-Array, welches als Begrenzung mit 0 abgeschlossen wird. s. Nullterminierung.

Gruß,

Karlito
Auf diesen Beitrag antworten »
InformaTiger

Anderer Tag - ähnliches Problem: ich schreibe eine Funktion welche mir aus einer Datei alle Zeilen schrittweise (mit angegebener Buffergröße) in einen String bzw. in ein Char-Array schreiben soll. Die Funktion macht ihre Aufgabe, das Problem ist, ich verstehe nicht warum. Sie sollte meiner Meinung nach, nach dem ersten Durchlauf durch die Schleife mit einem Fehler abbrechen. Ich schreibe eigentlich außerhalb des Speicherbereiches raus verwirrt

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
char * read(char *filename, int buffer_size){
    char *content = malloc(buffer_size * sizeof(char));
    char buffer[buffer_size];
    
    FILE *file = fopen(filename, "r");

    while (fgets(buffer, buffer_size, file) != NULL){
        strcat(content, buffer);
    }
    fclose(file);
    
    return content;
}


Wenn meine Annahme stimmt und C das nur aus irgendeinem unerdenklichen Grund macht, müsste ich content in der Schleife jedes mal realloziieren. Welche Funktion soll ich dafür verwenden? sizeof(content) oder strlen(content).

Die Rechnung müsste realloc(content, funktion(content) + buffer_size) lauten...

Mit freundlichen Grüßen
informaTiger
Auf diesen Beitrag antworten »
Karlito

Hallo Informatiger,

in C wird das überschreiten von Arrays nicht geprüft. Das musst Du selbst machen. Das Schreiben über das Array hinaus kann recht lange gut gehen. Ich vermute, dass spätestens dann, wenn Du >4Kb schreibst, das Betriebssystem schreit, weil Du die aktuelle Seite verlässt und dann keine Berechtigung mehr hast. Früher konnte soetwas in der Art für Pufferüberläuft genutzt werden. Heute ist das weit schwerer.

Bitte auch beachten, dass dir sizeof nur die Größe des Datentyps zurückgibt. Wenn Du das auf einen "String" anwenderst bekommst Du wahrscheinlich 8 zurück, weil Du einen Pointer au das erste Element des Char-Arrays übergibst. 64bit = 8 Byte -> sizeof(char *) = 8.

Gruß,

Karlito
 
 
Neue Frage »
Antworten »


Verwandte Themen

Die Beliebtesten »
Die Größten »
Die Neuesten »