C realloc - invalid old size

Neue Frage »

Auf diesen Beitrag antworten »
InformaTiger C realloc - invalid old size

Hallo,

ich arbeite gerade an einer Anwendung in welcher ich enorm große Zahlen addieren muss. Habe mir hierfür eine kleine Bibliothek geschrieben, die aber leider einen Fehler enthält:

Zitat:
*** Error in `./euler13': realloc(): invalid old size: 0x0000000001a22030 ***
Abgebrochen (Speicherabzug geschrieben)


Mein Quelltext hierfür sieht folgendermaßen 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:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
// numbers.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "numbers.h"

// [...] Funktionssignaturen

Number* init_number(char* data){
    Number* number = malloc(sizeof(Number));
    if (number == NULL){
        return NULL;
    }
    int length = strlen(data);

    number->data = malloc(length * sizeof(char));
    if (number->data == NULL){
        free(number);
        return NULL;
    }
    strcpy(number->data, data);
    number->length = length;

    return number;
}

bool number_add(Number* n1, const Number* n2){
    if (n1 == NULL || n2 == NULL){
        return false;
    }

    for (int i = n2->length - 1, j = n1->length - 1; i >= 0; i--, j--){
        int r = ctoi(n1->data[j]) + ctoi(n2->data[i]);
        align(n1, j, r);
    }
    return true; 
}

void align(Number* number, const int index, const int n){
    number->data[index] = itoc(n % 10);

    if (n >= 10){
        int r = ctoi(number->data[index - 1]) + (n / 10);
        if (r >= 10 && index - 1 <= 0){
            number->length++;
            number->data = realloc(number->data, number->length * sizeof(char));

            number->data[number->length - 1] = '\0';
            for (int i = number->length - 2; i > 0; i--){
                char temp = number->data[i - 1];
                number->data[i - 1] = number->data[i];
                number->data[i] = temp;
            }
        }

        if (r >= 10){
            align(number, index - 1, r);
        } else {
            number->data[index - 1] = itoc(r);
        }
    }
}


code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
// main.c
#include <stdio.h>
#include <stdlib.h>
#include "numbers.h"

#define COUNT 100

char* NUMBERS[COUNT] = {
    // [...]
    "17423706905851860660448207621209813287860733969412", /* die Zahl bei der der Fehler passiert */
   // [...]
};

int main(void){
    Number* r = init_number(NUMBERS[0]);

    for (int i = 1; i < COUNT; i++){
        Number* n = init_number(NUMBERS[i]);
        number_add(r, n);

        free_number(n);
        n = NULL;
    }
    free_number(r);

    return EXIT_SUCCESS;
}


Der Fehler bezieht sich auf Zeile 45 in numbers.c. Das einzige, dass mir bisher aufgefallen ist ist, dass der Number Pointer n in der Hauptfunktion immer derselbe ist obwohl ich ihn wieder freigebe; auch der Pointer data vom struct Number scheint konstant zu sein bzw immer wieder dieselbe Adresse zu erhalten.

verwirrt

Hat jemand vielleicht eine Idee, woran das liegen könnte?

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

Gibt es einen Grund, dass du das neu schreibst und keine Bibliothek verwendest (z.B. boost)?

Dein Code ist unvollständig. Ihn ausführen zu können, hilft bei der Fehlersuche, ist so aber nicht möglich.

Ich weiß nicht, ob das mit deinem Absturz zu tun hat, ist aber definitiv falsch:
code:
1:
2:
3:
char* data = "1234";
char* target = malloc(strlen(data) * sizeof(char)); //entspricht Zeile 14+16
strcpy(data, target); //Zeile 21

strlen liefert die Länge ohne terminierende 0. strcpy will die '\0' mit kopieren, du hast aber nicht so viel Speicher reserviert. Wenn ich den Code ausführe stürzt bei mir zwar nichts ab, aber verlassen würde ich mich darauf nicht.
In Zeile 46 machst du einen ähnlichen Fehler. Ich denke, dort ist der Absturz (du schreibst 45).
Auf diesen Beitrag antworten »
InformaTiger

Der Grund warum ich das neu schreibe ist, da ich mein Algorithmendenken bzw meine Programmiermethodik verbessern möchte smile ich lerne gerade auf eine Klausur und deshalb habe ich das selbst implementiert.

Ich habe das mit dem null terminierer zwar auch vermutet, nachdem ich das length * sizeof(char) durch ein ++length * sizeof(char) ausgetauscht habe und festgestellt habe, dass dies keinen Unterschied macht hab ich es wieder zurückgeändert - werd ich aber auf jeden Fall nochmals anpassen.

Ich lade den Quelltext heute nachmittag hoch, habe ihn nur leider grade nicht bei der Hand. Ja, das mit Zeile 46 stimmt; habe den Kommentar // numbers.c erst nachträglich hinzugefügt weswegen es sich verschoben hat.

Danke inzwischen. Augenzwinkern

Edit: habe den Quelltext im Beitrag nun angehängt.

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

Hätte dein Edit fast nicht gesehen. Wenn ein paar Stunden dazwischenliegen, schreibe besser einen neuen Beitrag. Jetzt verstehe ich, Project Euler smile

ein number->data = malloc((1+length) * sizeof(char)); in Zeile 17 sollte es richten. Es kommt zwar noch nichts richtiges raus, aber es läuft durch.

Was machst du, wenn beide Zahlen verschieden lang sind?
 
Auf diesen Beitrag antworten »
InformaTiger

Oh, ok. Ich dachte nur ich will nicht mit Beiträgen "vollspammen", aber ok - fürs nächste mal schreib ich einfach einen neuen smile
Leider läuft das Programm immer noch nicht durch. Ich bekomme immer noch denselben Fehler als vorhin unglücklich

Ob die Zahlen unterschiedlich lang sind, ist in diesem Kontext unerheblich da diese Zahlen mit denen ich rechne so oder so gleich lang sind. Für meine Funktion number_add gilt jedoch dass Parameter 1 (also die erste Zahl) größer bzw länger oder gleich lang der 2. Zahl ist.

Edit: hab mir gedacht, dass es vielleicht daranliegt, dass ich einen string der mit strcpy angelegt wurde nicht mit realloc reallozieren kann. Leider hat memcpy aber auch nicht geholfen

Mit freundlichen Grüßen
InformaTiger
 
Neue Frage »
Antworten »


Verwandte Themen

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