Paules-PC-Forum.de Anzeige:

Microsoft Windows Intune: PC-Verwaltung und -Sicherheit in der Cloud: Updateverwaltung, Anti-Virus und vieles mehr!


Zurück   Paules-PC-Forum.de > Programmierung > C/C++, Visual C++, Visual C++.NET

C/C++, Visual C++, Visual C++.NET Fragen und Antworten zu C/C++, Visual C++ und Visual C++.NET

EM-Tippspiel

Paule bei Facebook


Paule bei Twitter


Letzte Forenthemen
Gehe zum ersten neuen Beitrag PPF - Shoppingwahn
Aufrufe: 50849, Antworten: 1390
Gehe zum ersten neuen Beitrag PPF - Spiel "Wörter weiter...
Aufrufe: 26615, Antworten: 4194
Gehe zum ersten neuen Beitrag Windows Oberfläche (Schrift,...
Aufrufe: 176, Antworten: 10
Gehe zum ersten neuen Beitrag Von Live CD Windowspfad...
Aufrufe: 63, Antworten: 5
Gehe zum ersten neuen Beitrag TabCtrl
Aufrufe: 121, Antworten: 12
Gehe zum ersten neuen Beitrag Rechner fährt herunter,...
Aufrufe: 93, Antworten: 4
Gehe zum ersten neuen Beitrag Dateien lassen sich nicht...
Aufrufe: 17, Antworten: 2
Gehe zum ersten neuen Beitrag Suche Programm um Werbung zu...
Aufrufe: 49, Antworten: 2
Gehe zum ersten neuen Beitrag McAfee AVERT Stinger...
Aufrufe: 13, Antworten: 0
Gehe zum ersten neuen Beitrag Sticky Password 6.0.2...
Aufrufe: 25, Antworten: 0
Zeige:





Antwort
 
LinkBack Themen-Optionen Ansicht
Alt 05.02.2010, 21:42   #1 (Direktlink)
Weiß worum´s geht
 
Registriert seit: 31.03.2009
Ort: localhost
Beiträge: 222
Standard C: Speicherzugriffsfehler

Guten Abend allerseits

Ich wollte mir mal ein paar nützliche Funktionen in C schreiben, die funktionieren auch super. Allerdings hab ich die jetzt mal testweise kombiniert und jetzt fängt es an zu hacken.
Die Datei um die es geht, ist angehängt. Ich nutze gcc (Debian 4.3.3-3) 4.3.3
Beim compilen funktioniert alles wunderbar, allerdings beim starten kommen Fehler.
Wenn ich in die char **explode funktion in die while schleife ein i<[1-8] packe, kommt am Ende nur ein Speicherzugriffsfehler, andernfalls (so wie die Datei ist) kommt noch realloc(): invalid next size....
Ich komme echt nicht darauf, wo der Fehler liegen sollte, da die Ausgabe diese hier ist:
Code:
x: # 
x: #i 
x: #in 
x: #inc 
x: #incl 
x: #inclu 
x: #includ 
x: #include 
x: #include  
x: #include < 
x: #include <s 
x: #include <st 
*** glibc detected *** ./a.out: realloc(): invalid next size
Und zwar wird die Ausgabe von "x: " direkt nach while(..) { gestartet und die Ausgabe von "%s\n" direkt vor } Deswegen weiß ich nicht, wo der Fehler liegen sollte.
Vll kann mir hier jemand helfen
Ansonsten wüsste ich noch gerne, ob die Funktionen sicher sind (BOFs) und ob sie Speicherlecks enthalten. Danke schonmal

Geändert von Schwert (11.02.2010 um 15:56 Uhr)
Schwert ist offline   Mit Zitat antworten
Werbung

Windows 7 Tipps und Tricks in Bildern

Alt 06.02.2010, 19:53   #2 (Direktlink)
War schon mal da
 
Registriert seit: 06.02.2010
Beiträge: 27
Standard

Sorry, aber ich steig durch deinen Code nicht durch. Ein paar Fragen:
1) Warum alloziierst du alle möglichen lokalen Variablen auf dem Heap? Das bringt keinerlei Vorteil und verwirrt nur.
2) Was ist der Sinn dieser Zeile: "tmp = malloc(0*sizeof(char));"
3) Wieso wird im folgenden Code 2mal überprüft ob size==NULL?
Code:
	if(size == NULL) {
		return NULL;
	}

	if(NULL == size) {
		free(tmp);
		free(arr);
		return explode(str, delimiter, lim, size);
	}
4) Wieso prüfst du die Rückgabewerte von malloc? Programmierst du für Embedded Systeme? Weil ansonsten ist ein Ausschöpfen des Speichers ziemlich unwahrscheinlich.
cx01 ist offline   Mit Zitat antworten
Alt 06.02.2010, 22:21   #3 (Direktlink)
Weiß worum´s geht
 
Registriert seit: 31.03.2009
Ort: localhost
Beiträge: 222
Standard

cx01: Danke für deine Antwort.
zu 1: Manche der Funktionen hab ich geschrieben, wie ich angefangen habe C zu lernen. Damals dachte ich, man benutzt malloc/calloc/realloc, weil wenn man einfach nur "int i=bla" benutzt, ein Speicherleck hat, wenn das öfter aufgerufen wird (in einer Schleife ist), weil ich dachte, dass der Speicher nicht wieder freigegeben wird. Das war dort wo ich es gelernt habe ziemlich missverständlich erklärt, mittlerweile weiß ich es besser. Außerdem finde ich es in manchen Fällen einfacher/schöner mit Zeigern/eigenem reserviertem Speicher zu arbeiten

zu 2: Der Sinn davon ist, dass, bevor ich realloc anwende, malloc oder calloc anwenden muss. realloc wird später in der Schleife benutzt. Mann kann auch 1*sizeof(char) machen, allerdings ist dann immer die Größe eines chars zuviel und ich dachte mir, ich lass es lieber genausogroß wieder Inhalt

zu 3: Das mit dem Size stimmt, das war mein Fehler und zwar hab ich das erst gemacht, wie bei jeder Alloziierung um zu testen, ob es geklappt hat, bis mir aufgefallen, dass size ein Parameter ist um die größe das Arrays zurückzugeben. Bzw hab ich dies im nachhinein geändert. Ich werde 2. rausnehmen, danke

zu 4: In gewisserweiße ja, die Aufgabe des aktuellen Projektes ist zwar nicht lebensnotwendig für das System, allerdings ist es ein wichtiger Bestandteil der Sicherheit des Systems und ich will auch sicher programmieren. Da ich die Funktionen in verschiedenen Projekten verwenden werde, will ich sie halt einmal richtig programmieren.

Ich hab die Datei jetzt noch klein wenig verändert und hab sie nochmals angehängt

Geändert von Schwert (11.02.2010 um 15:56 Uhr)
Schwert ist offline   Mit Zitat antworten
Alt 06.02.2010, 22:25   #4 (Direktlink)
War schon mal da
 
Registriert seit: 06.02.2010
Beiträge: 27
Standard

Und was ist der Sinn der Explode Funktion? Sie zerteilt einen String in mehrere Teilstrings? Was bewirken die Parameter lim und size?
cx01 ist offline   Mit Zitat antworten
Alt 06.02.2010, 22:31   #5 (Direktlink)
Weiß worum´s geht
 
Registriert seit: 31.03.2009
Ort: localhost
Beiträge: 222
Standard

size ist ein Zeiger für die größe des Arrays. Der Speicher wird vor dem aufruf der Funktion vom Programmierer reserviert und somit kann ich quasi mehrere Werte "returnen", da ja die Speicheraddresse gespeichert ist und ich nur den Wert ändere.
lim ist das Limit, wie groß das Array maximal werden darf.
Edit: Ja, das ist der Sinn der explode Funktion
Schwert ist offline   Mit Zitat antworten
Werbung

Windows 7 Tipps und Tricks in Bildern

Alt 07.02.2010, 00:32   #6 (Direktlink)
War schon mal da
 
Registriert seit: 06.02.2010
Beiträge: 27
Standard

Ich bin leider durch deinen Code nicht durchgestiegen und hab mal eine eigene Variante programmiert. Gut möglich, dass da noch Bugs drinstecken. Bin leicht übermüdet
Code:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

char **explode(char *str, char *delimiter, int *arr_size) 
{
    int str_len = strlen(str);
    int delimiter_len = strlen(delimiter);
    
    int i = 0;
    int start_of_match = 0;
    int end_of_match = 0;
    int matched = 0;
    
    *arr_size = 0;
    char **arr = malloc(*arr_size*sizeof(char*));
    
    while(1)
    {
        end_of_match = i;
        matched = 0;
        
        while(str[i+matched] == delimiter[matched])
        {
            matched++;
         
            if(matched==delimiter_len || i+matched>=str_len)
            {
                //wir haben ein match
                i += matched;
                int match_len = end_of_match - start_of_match;
                if(match_len == 0) 
                {
                    start_of_match = i;
                    break;
                }

                char* res = malloc((1 + match_len) * sizeof(char));
                memcpy(res, str + start_of_match, match_len);
                res[match_len] = 0;
                
                //array vergroessern
                *arr_size += 1;
                arr = realloc(arr, *arr_size*sizeof(char*));
               
                //match ins array einfügen
                arr[*arr_size-1] = res;
                            
                
                start_of_match = i;
                if(i>=str_len) return arr;
                break;
            }
        }
        
        i++;
    }

}


int main()
{
    char* m = "tABC1953ABC59209ABCD34ABC";
    char* d = "ABC";
    int elems = 0;
    char **arr = explode(m, d, &elems);
    
    int i=0;
    for(;i<elems;i++)
    {
        printf("%s\n", arr[i]);
    }
    
    
}
cx01 ist offline   Mit Zitat antworten
Alt 07.02.2010, 10:30   #7 (Direktlink)
Weiß worum´s geht
 
Registriert seit: 31.03.2009
Ort: localhost
Beiträge: 222
Standard

Ok, danke!
Deine Variante ist schonmal viel übersichtlicher als meine xD
Werde mir da wohl dann auch n Beispiel dran nehmen.

Bei so einem normalen String funktioniert meine explode Funktion auch
Ich hab jetzt einfach mal deine explode Funktion in meinen Code eingefügt und dann den Funktionsaufruf noch angepasst. Wenn ich jetzt *file_get_contents("mysql_check.c"); als *str nehme, dann bekomm ich zwar diesmal das ganze Ergebnis, ohne realloc Fehler, allerdings steht unterdem ganzen wieder Speicherzugriffsfehler.
Ich hänge die Datei nochmals an
Du musst die Datei nur in mysql_check.c umbennenen, da ist hier keine *.c Dateien hochladen kann.
Wo steigst du den bei meinem Code noch nicht durch? Dann kann ich es dir vll erklären oder das was du nicht verstehst ist genau mein Fehler

Edit: Ich sehe gerade, die letzte Zeile der Datei wird bei deiner Funktion dann nicht ausgegeben

Geändert von Schwert (11.02.2010 um 15:56 Uhr)
Schwert ist offline   Mit Zitat antworten
Alt 07.02.2010, 13:27   #8 (Direktlink)
War schon mal da
 
Registriert seit: 06.02.2010
Beiträge: 27
Standard

Die file_get_contents Methode scheint fehlerhaft zu sein, zumindest krieg ich eine Exception an folgender Stelle (in der Zeile mit strncat):
Code:
	if(datei != NULL) {
		while( (*zeichen = getc(datei)) != EOF) {
			strncat(str, zeichen, 2);
		}
	}
Benutzt du eig einen Debugger?

Was ich an deinem Code nicht verstehe? Nunja, ist natürlich immer leichter den eigenen Code zu lesen, und irgendwie glaub ich, dass dein Code komplizierter ist als er sein müsste.

EDIT: Ich seh grad, die file_get_contents Funktion ist extrem ineffizient. Normalerweise benutzt man fread() oder fgets() für solche Situationen.

Geändert von cx01 (07.02.2010 um 13:39 Uhr)
cx01 ist offline   Mit Zitat antworten
Alt 07.02.2010, 14:48   #9 (Direktlink)
Weiß worum´s geht
 
Registriert seit: 31.03.2009
Ort: localhost
Beiträge: 222
Standard

file_get_contents hab ich mehrfach getestet und genutzt. Bei mir funktioniert die Funktion fehlerfrei, auch wenn ich die Variable ausgebe.
Nein, ich nutze keinen Debugger, ich lass mir nur verschiedene Variablen beim programmieren ausgeben oder schreib sie manchmal auch in Dateien.

Du hast Recht, mein Code ist/war viel zu umständlich, bin mittlerweile hier

Code:
char **explode(char *str, char *delimiter, int lim, int *size) { 
    if(size == NULL) {
        return NULL;
    }
    *size = 1;
    char **arr;
    arr = (char **)malloc(*size*sizeof(char **));
    if(NULL == arr) {
        return explode(str, delimiter, lim, size);
    }

    int limit;
    if(lim < 0) {
        limit = 1;
    } else {
        limit = lim;
    }
    char *test;
    char *tmpt;
    int i = 0;
    int delimiter_len = strlen(delimiter);
    int str_len = strlen(str);
    int z = 0;

    while(*size < limit && i < str_len) {
        test = substr(str, i, delimiter_len);
        if(strncmp(test, delimiter, delimiter_len) == 0) {
            if(lim < 0) {
                limit++;
            }
            (*size)++;
            z++;
            arr = (char **)realloc(arr, (*size)*sizeof(char *));                        //nulltest
            i += delimiter_len;
        } else {
            tmpt = substr(str, i, 1);
            if(NULL == arr[z]) {
                arr[z] = tmpt;
            } else {
                arr[z] = (char *)realloc(arr+(z), sizeof(arr[z])+sizeof(tmpt));    //nulltest
                strncat(arr[z], tmpt, strlen(tmpt));
                free(tmpt);
            }
            i++;
        }
        free(test);
    }
    return arr;
}
klappt allerdings leider immer noch nicht
ich werde mir file_get_contents dann noch mal anschauen

Edit: Die Fehler liegen bei
arr[z] = (char *)realloc(arr+(z), sizeof(arr[z])+sizeof(tmpt));
und
strncat(arr[z], tmpt, strlen(tmpt));
Allerdings bekomm ich die Fehler nicht weg
Schwert ist offline   Mit Zitat antworten
Alt 07.02.2010, 15:16   #10 (Direktlink)
War schon mal da
 
Registriert seit: 06.02.2010
Beiträge: 27
Standard

Ich kriege eine Exception im malloc() Aufruf in der Funktion substr. Das kann eig nicht sein, daher vermute ich, dass du irgendwo ausversehen Speicherbereiche überschreibst, in die du nicht schreiben solltest. Weiss jedoch noch nicht wo...

EDIT: Die von dir gepostete Stelle könnte der Fehler sein. Ich glaube sizeof(arr[z]) gibt nicht die Länge des Array, sondern nur die sizeof(char*) zurück.
cx01 ist offline   Mit Zitat antworten
Werbung

Windows 7 Tipps und Tricks in Bildern

Alt 07.02.2010, 16:18   #11 (Direktlink)
Weiß worum´s geht
 
Registriert seit: 31.03.2009
Ort: localhost
Beiträge: 222
Standard

Ich hab die Funktion file_get_contents jetzt mal umgeschrieben:
Code:
char *file_get_contents(char *filename) {
    if(file_exists(filename) == 0) {
        return NULL;
    }
    FILE *datei;
    char *str = NULL;
    fpos_t *size = NULL;
    datei=fopen(filename, "r");
    if(NULL == datei) {
        return file_get_contents(filename);
    }

    size = (fpos_t *)malloc(sizeof(fpos_t));
    if(NULL == size) {
        free(datei);
        return file_get_contents(filename);
    }

    fgetpos(datei, size);

    str = (char *) malloc((size_t)size);
    
    if(NULL == str) {
        free(datei);
        return file_get_contents(filename);
    }

    fread(str, sizeof(char), (size_t)size, datei);
    free(size);
    free(datei);
    return str;
}
Hoffe das ist besser Scheint mir auch auf den ersten Blick schneller, danke

das mit der Exception wundert mich jetzt auch etwas.
Es kann nicht daran liegen, dass ich:
tmpt = substr(str, i, 1);
if(NULL == arr[z]) {
arr[z] = tmpt;
}
und arr[z] danach mit realloc erweitere?

und du hattest Recht: sizeof(arr[z]) gibt nur sizeof(char) zurück
Ich hatte vorhin testweise sizeof(arr[z]) ausgegeben und mich gewundert, warum es 1000 mal hintereinander nur 4 ist, obwohl es ja durch realloc lief.
Die Zeile sieht jetzt so aus:
arr[z] = (char *)realloc(arr+(z), strlen(arr[z])+sizeof(tmpt));

hab die Datei jetzt noch mal hochgeladen.
Wenn ich in Zeile 173 printf("%s\n", arr[z]); einkommentiere, sehe ich, dass die Datei anscheinend mehrmals durchlaufen wird, was mir gerade komisch vorkommt und ich bin deshalb leicht verwirrt

Ok:
hab das jetzt so aufgerufen:
gcc mysql_check.c && ./a.out | grep *file_get
und es kommt so oft, dass ich in der shell oben nichts anderes mehr sehe.

Was nutzt du den für einen Debugger?

Geändert von Schwert (11.02.2010 um 15:56 Uhr)
Schwert ist offline   Mit Zitat antworten
Alt 07.02.2010, 17:29   #12 (Direktlink)
War schon mal da
 
Registriert seit: 06.02.2010
Beiträge: 27
Standard

Zur file_get_contents Methode: Sieht auf den ersten Blick gut aus. Ich würde alle lokalen Variablen auf dem Stack alloziieren; das ist leichter zu lesen und performanter.

Als Debugger benutze ich Visual C++ 2008 Express; falls du Windows User bist, kannst du dir das kostenlos downloaden.

Woran die Exception liegt, weiss ich immernoch nicht Vermutlich wirst du es mit einem Debugger schneller rausfinden als ich.
cx01 ist offline   Mit Zitat antworten
Alt 08.02.2010, 16:45   #13 (Direktlink)
Weiß worum´s geht
 
Registriert seit: 31.03.2009
Ort: localhost
Beiträge: 222
Standard

Ok, also ich probiere es jetzt seit heut und gestern mit einem Debugger zufinden.
Ich hab das Gefühl, dass in der file_get_contents Funktion ein Fehler vorliegt.

Wenn mann str=file_get_contents("path/to/file.endung"); free(str); macht, kommt kein Fehler, gebe ich jetzt allerdings noch printf("%s\n", str); dazwischen ein, kommt:
Code:
Conditional jump or move depends on uninitialised value(s)
    at 0x4025BC7: strlen (mc_replace_strmem.c:275)
    by 0x4092D94: puts (ioputs.c:36)
    by 0x8048E7D: main (in a.out)
auch wenn ich in der explode Funktion strlen(str) habe, kommt ein "Conditional jump or move depends on uninitialised value"-Fehler, was im Grunde sagt, dass die Variable nicht inializiert ist?
Das Ergebnis von strlen ist aber 383, was genau dem Inhalt der Datei entspricht, auch printf() gibt den Inhalt richtig aus.

Edit: Ich hänge die Datei nochmal an

Geändert von Schwert (11.02.2010 um 15:56 Uhr)
Schwert ist offline   Mit Zitat antworten
Alt 08.02.2010, 22:15   #14 (Direktlink)
War schon mal da
 
Registriert seit: 06.02.2010
Beiträge: 27
Standard

Hier ist ein Beispiel, wie man eine Datei einliest: fread - C++ Reference
Kannst du eig direkt übernehmen.
cx01 ist offline   Mit Zitat antworten
Alt 08.02.2010, 22:46   #15 (Direktlink)
Weiß worum´s geht
 
Registriert seit: 31.03.2009
Ort: localhost
Beiträge: 222
Standard

danke!
Habs übernommen, bekomme allerdings immer noch den gleichen Fehler.
Entweder sollte ich das Programmieren aufgeben oder mir nen Strick suchen, ich verzweifle hier echt

Vllt sollte man diesen "Fehler" auch einfach nicht beachten?
Schwert ist offline   Mit Zitat antworten
Werbung

Windows 7 Tipps und Tricks in Bildern

Antwort

  Paules-PC-Forum.de > Programmierung > C/C++, Visual C++, Visual C++.NET

Lesezeichen

Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen erlaubt, neue Themen zu verfassen.
Es ist Ihnen erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Speicherzugriffsfehler tobi.-.-.-. C/C++, Visual C++, Visual C++.NET 3 18.05.2005 14:33



Alle Zeitangaben in WEZ +2. Es ist jetzt 05:07 Uhr.


Powered by vBulletin® Version 3.8.7 (Deutsch)
Copyright ©2000 - 2012, vBulletin Solutions, Inc.
Powered by vBCMS® 2.7.0 ©2002 - 2012 vbdesigns.de
(c) Paules-PC-Forum.de

::: Impressum :::

Search Engine Optimization by vBSEO 3.3.2