C Char Array Pointer neu beschreiben

Tester-Testet

Cadet 2nd Year
Registriert
Aug. 2018
Beiträge
26
Hallo zusammen,

ich habe ein Problem in C, aber erst einmal den Quellcode:

C:
        #define LineDlm 13

        char * temp;
        int tmp = LineDlm;
        char * Keys = malloc(4 * sizeof(char));
         Keys[0] = 'H';
         Keys[1] = '\0';

        printf("Das steht in Keys: %c \n", Keys[0]);

        printf("\n-> ");
        for (i = 0; (tmp = getkey()) != LineDlm; i++)
        {
            if (sizeof(Keys) < i + 1)
            {
                printf("Will den Speicher erweitern\n");
                temp = calloc(i + 3, sizeof(char));
                temp = Keys;
                Keys = calloc(i + 3, sizeof(char));
                Keys = temp;
            }
            printf("tmp: %c\n",tmp);
            printf("I: %i\n",i);
            Keys[i] = tmp;
            printf("Keys: %c\n",Keys[i]);
            Keys[i + 1] = '\0';
        }

Mein Problem ist einfach, das ich nichts in Keys rein schreiben kann. Ich kann weder in der mit "Keys[0] = 'H';" etwas in den 1. Baustein reinschreiben, weder noch mit "Keys = tmp;". Was muss ich verändern, das ich etwas überschreiben kann.

Danke für Hilfe.
 
Das sollte eigentlich funktionieren, wie sieht denn die Ausgabe aus?

Edit: Was gibt er denn aus wenn du einfach mal den ganzen String ausgibst?

C:
printf("String: %s", Keys);
 
Ebrithil schrieb:
Das sollte eigentlich funktionieren, wie sieht denn die Ausgabe aus?

1536909160401.png

Wie man sehen kann, liegen nur zufällige random Chars in Keys.
Ergänzung ()

Ebrithil schrieb:
Das sollte eigentlich funktionieren, wie sieht denn die Ausgabe aus?

Edit: Was gibt er denn aus wenn du einfach mal den ganzen String ausgibst?

C:
printf("String: %s", Keys);

1536909698111.png
 
Zuletzt bearbeitet:
Na bitte, da hast du deine Antwort, irgendwas geht beim Speicher reservieren schief.

Du musst nach jedem calloc/malloc prüfen, ob du einen Null Pointer zurück bekommen hast.

Edit: ahhhhh zu lange kein C mehr gemacht...

da liegt noch ein Fehler:
if (sizeof(Keys) < i + 1)

sizeof(Keys) liefert immer sizeof(char*) zurück (-> die Größe eines Pointers also entweder 4 oder 8 byte!) und nicht die Größe deines Arrays! Die musst du dir einzeln speichern und merken.

Edit2:
Und du solltest realloc statt calloc verwenden wenn du Speicherbereiche vergrößern oder verkleinern willst. Du hast da einen ganz üblen Memory leak drin, wenn du einfach neuen Speicher reservierst ohne den alten freizugeben.
 
Zuletzt bearbeitet:
Ebrithil schrieb:
Na bitte, da hast du deine Antwort, irgendwas geht beim Speicher reservieren schief.

Du musst nach jedem calloc/malloc prüfen, ob du einen Null Pointer zurück bekommen hast.

Edit: ahhhhh zu lange kein C mehr gemacht...

da liegt noch ein Fehler:
if (sizeof(Keys) < i + 1)

sizeof(Keys) liefert immer sizeof(char*) zurück (-> die Größe eines Pointers also entweder 4 oder 8 byte!) und nicht die Größe deines Arrays! Die musst du dir einzeln speichern und merken.

Edit2:
Und du solltest realloc statt calloc verwenden wenn du Speicherbereiche vergrößern oder verkleinern willst. Du hast da einen ganz üblen Memory leak drin, wenn du einfach neuen Speicher reservierst ohne den alten freizugeben.

Das Problem beginnt schon beim 1. Malloc:

1536911009373.png
 
Versuche mal
Code:
char *Keys = (char*)malloc(4 * sizeof(char))

malloc gibt einen void-Pointer zurück, je nach Compiler beschwert er sich auch. Wenn es das nicht ist, musst du schauen, welcher Fehler malloc auswirft.
 
Seltsam, das sollte eigentlich gehen.

Ist das alles was dein Programm macht? Afaik kann malloc failen wenn du vorher schon speicher corruptet hast.
 
Hier ist jetzt nochmal eine Version die auf einem ganz normalen gcc Compiler Funktioniert, aber hier nicht:

Code:
        int tmp = LineDlm;
        char * Keys = malloc(1);
        Keys[0] = '\0';

        if (!Keys)
        {
            printf("Geht jetzt schon nicht!\n");
        }

        printf("\n-> ");
        for (int i = 0; (tmp = getkey()) != LineDlm; i++)
        {
            if ((i * sizeof(Keys)) < i + 2)
            {
                char * temp = malloc(i + 2 + sizeof(char));
                for(x = 0; x <= i; x++)
                {
                    temp[x] = Keys[x];
                    temp[x + 1] = '\0';
                }
                temp[x] = '\0';
                free(Keys);
                Keys = temp;
            }
            printf("tmp: %c\n",tmp);
            printf("Size: %i\n",sizeof(Keys));
            printf("I: %i\n",i);
            Keys[i] = tmp;
            printf("Keys: %c\n",Keys[i]);
            Keys[i + 1] = '\0';
        }

Aber hier nicht.

INFO: das ist der Image Craft Cortex M Compiler.

Trotzdem sollte es doch möglich sein Malloc, bzw. schon funktionierenden Code zu kompelieren.
 
Ist schon sehr lange her, aber glaube du solltest dir die Pointer Arithmetic nochmal genauer anschauen.

Code:
temp = calloc(i + 3, sizeof(char)); <<< Speicher wird allokiert
temp = Keys; <<< Hier wird doch nur ein Pointer übergeben, aber nicht der Inhalt
Keys = calloc(i + 3, sizeof(char)); << Speicher wird allokiert
Keys = temp; <<< Hier wird doch nur ein Pointer übergeben, aber nicht der Inhalt


In dem anderen Code ist das kopieren des Inhaltes enthalten,

Code:
                for(x = 0; x <= i; x++)
                {
                    temp[x] = Keys[x];
                    temp[x + 1] = '\0';    << schein unnötig zu sein, bei die Iteration 1 ist und beim nächsten durchlauf wird das Feld überschrieben
                }
                temp[x] = '\0';
 
Zuletzt bearbeitet:
isiprimax schrieb:
Ist schon sehr lange her, aber glaube du solltest dir die Pointer Arithmetic nochmal genauer anschauen.

Code:
temp = calloc(i + 3, sizeof(char)); <<< Speicher wird allokiert
temp = Keys; <<< Hier wird doch nur ein Pointer übergeben, aber nicht der Inhalt
Keys = calloc(i + 3, sizeof(char)); << Speicher wird allokiert
Keys = temp; <<< Hier wird doch nur ein Pointer übergeben, aber nicht der Inhalt


In dem anderen Code ist das kopieren des Inhaltes enthalten,

Code:
                for(x = 0; x <= i; x++)
                {
                    temp[x] = Keys[x];
                    temp[x + 1] = '\0';    << schein unnötig zu sein, weil der Iteration nur 1 ist und beim nächsten durchlauf wird das Feld überschrieben
                }
                temp[x] = '\0';
Aber warum geht es dann nicht ?

Das Problem muss schon bei Initalisierungs malloc liegen, aber wie prüft man da weiter, bzw. was kann ich da machen?
 
Versuch es Simpel

temp = neuer Speicher an Adresse 1
temp = zeigt auf Adresse von Keys die ist 2
Keys = neuer Speicher und neue Adresse 3
Keys = zeigt auf Adresse von Temp was vorher Keys war also 2

Du übergibst nur die Adresse des Speichers, aber nicht den Inhalt.

edit: malloc und calloc geben neue Speicheradresse zurück
 
Zuletzt bearbeitet:
Ich kenne den Compiler nicht, aber ich habe auf die schnelle das hier gefunden:

The Standard Library header file <stdlib.h> defines the macros NULL and RAND_MAX and typedefs size_t
and declares the following functions. Note that you must initialize the heap with the _NewHeap call before using any of the memory allocation routines (calloc, malloc, and, realloc).

Quelle (S.115)

Das würde auch erklären, wieso dein malloc immer fehlschlägt, weil der Heap nicht initialisiert ist

Edit:

Das was @isiprimax angemerkt hat musst du dir wirklich nochmal anschauen, da wirst du in die nächsten Probleme reinlaufen. Wenn du einen Speicherbereich kopieren willst, geht das nicht über eine Zuweisung. Du müsstest dafür etwas wie memcpy nutzen (besser als eine for-Schleife).
Außerdem ist es essentiell, dass du Speicher wieder freigibst, den du allokiert hast. Du hättest in deinem Beispiel gleich mehrere memory leaks erzeugt.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Ebrithil und isiprimax
Zurück
Oben