probleme beim speicher allocaten



  • Hallo Zusammen.

    Ich bin neu hier in diesem Forum und habe schon vor der Registrierung oft von eurer Hilfe gebrauch machen können 😃

    Es wird wohl ein altbekanntes Problem sein das ich habe, kontne den Fehler aber nicht heraus kriegen bisher ;/

    Ich habe ein Serverprogramm das ein struct über eine named pipe vom client(cgi) erhält. wenn ich dieses struct erhalten habe, will ich ein char * als Antwort über eine neue named pipe senden. Dieser Teil funktioniert auch schon ganz gut. Mein Problem ist: Bei jedem struct das ich über die named Pipe sende, allocate ich mehr RAM für mein Serverprgramm... ich werde aber nicht fündig wo! Schlussendlich macht mein Programm naütlich probleme für den Server... da nach circa 20min die RAM voll sind.

    Codeausschnitt vom Serverprogramm für die Kommunikation mit dem Client:

    int com_client(int privatefifo, int publicfifo, int n, int done, struct message msg) {
        /*Lese nachricht von PUBLIC fifo*/
        if(read(publicfifo, &msg, sizeof(msg)) > 0) {
            //reset done und n variable
            n=0;
            done=0;
            //solange bis privatefifo erreicht oder 5 verbindungsversuche durch
            do {
                //checke ob private fifo geöffnet sonst kurzes usleep
                if((privatefifo = open(msg.fifo_name, O_WRONLY|O_NDELAY)) == -1) {
                    usleep(100);
                }
                else {
                    //schreibe daten aus Model in variabel als JSON-string
                    snprintf(mychar,sizeof(mychar),"%s",JSON(get_data()));
                    //schreibe JSON-String variable an Private Fifo
                    write(privatefifo,mychar,sizeof(mychar));
                    //schliesse Fifo
                    close(privatefifo);
                    //setze done variable
                    done = 1;
                }
            }while(n++ < 5 && !done);
            //wenn private fifo nicht erreicht
            if(!done) {
                //fehlermeldung
                perror("Not accessed the private fifo\n");
                return 1;
            }
            //ok
            return 0;
        }
        else {
            //fehler
            return 1;
        }
    }
    

    msg.struct:

    struct message {
        char fifo_name[30];
        char cmd_line[4060];
        int mycmd;
    };
    

    Das Programm läuft auf einem Olimex-Board mit Debian: Debian GNU/Linux 5.0 auf dme olimexboard sam9-l9260

    Vermutlich könnte ich den fehler mit Valgrind eindämmen. Ich muss aber sagen ich habe keine Ahnung von diesem Tool. Wenn mir wer sagen kann wie ich das verwende ist mir evtl schon geholfen.

    So long
    Bluefire

    ps: sagt mir wenn euch was fehlt um mir zu helfen 😃


  • Mod

    Bluefire schrieb:

    Vermutlich könnte ich den fehler mit Valgrind eindämmen. Ich muss aber sagen ich habe keine Ahnung von diesem Tool. Wenn mir wer sagen kann wie ich das verwende ist mir evtl schon geholfen.

    Du tippst valgrind programmname . Fertig.

    Oder in lang:
    http://valgrind.org/docs/manual/quick-start.html



  • dann installiere und teste ich doch gleich mal dieses Valgrind programm... falls ich selbst dahinter komme wo der fehler ist und wie er zu beheben ist melde ich meine lösung, sonst werde ich dann noch das Valgrind Resultat posten... jetzt aber mal schnell was futtern gehn 😃



  • Ich krieg das installieren nicht einmal hin.. Ich habe leider keine grosse Ahnung von linux!

    Zuerst führte ich folgenden Befehl aus zum vorbereiten der source packages

    apt-get build-dep valgrind

    dann bei einem apt-get install valgrind krieg ich folgende meldung:

    sam9-l9260:~# apt-get install valgrind
    Reading package lists... Done
    Building dependency tree
    Reading state information... Done
    Package valgrind is not available, but is referred to by another package.
    This may mean that the package is missing, has been obsoleted, or
    is only available from another source

    E: Package valgrind has no installation candidate
    sam9-l9260:~#

    bevor ich das nicht hinkriege wird wohl nichts mit nem valgrind-bericht 😕



  • Mein letzter Stand sagt mir, valgrind gibt es nicht für ARM. Es gab auch mal auf der Seite eine Übersicht, welche Tools, für welche Architektur verfügbar sind. Die finde ich aber jetzt nicht.

    gefunden:
    http://valgrind.org/info/platforms.html



  • ja das ist schade 😕

    hmmm... sieht einer mein speicherleck von Auge?
    kann sonst auch noch mehr code posten falls nötig



  • Lass das Programm doch auf deinem PC laufen. Sollte doch bei einer Linux-Anwendung keine größere Hürde sein. Dann kannst du auch valgrind nutzen.



  • Ich habe

    snprintf(mychar,sizeof(mychar),"%s",JSON(get_data()));
    

    im Verdacht. Fordern get_data oder JSON vielleicht Speicher an? Dieser würde auf diese Weise nämlich nicht freigegeben.



  • ich hab ein Model.h in diesem ist die get_Data funktion drin

    static int msgcmd = 0;
    static char * msgvalues;
    static struct canobject *data;
    
    int set_msgcmd(int mycmd){
        msgcmd = mycmd;
        return 0;
    }
    
    int set_msgvalues(char * myvalue){
        msgvalues = malloc(strlen(myvalue));
        msgvalues = myvalue;
        return 0;
    }
    
    int get_msgcmd(){
        return msgcmd;
    }
    
    char * get_msgvalues(){
        return msgvalues;
    }
    
    int set_data(struct canobject * mydata){
        data = malloc(sizeof(mydata));
        data = mydata;
        return 0;
    }
    
    struct canobject * get_data(){
        return data;
    }
    

    die JSON funktion sieht folgendermassen aus:

    char * JSON(struct canobject * myobject){
        char * ret;
        int i;
        //erstelle JSON array
        json_object *myarray = json_object_new_array();
        //mache bis keine Daten mehr vorhandensind
        for(i = 0; i < ANZ_OBJ;i++){
            //erstelle json objekt
            json_object *jobj = json_object_new_object();
            json_object *lab = json_object_new_string(myobject[i].lab);
            json_object_object_add(jobj, "label", lab);
            json_object *mon = json_object_new_double(myobject[i].mon);
            json_object_object_add(jobj, "monitor", mon);
            json_object *las = json_object_new_double(myobject[i].las);
            json_object_object_add(jobj, "lastset", las);
            json_object *sol = json_object_new_double(myobject[i].sol);
            json_object_object_add(jobj, "soll", sol);
            json_object *ein = json_object_new_string(myobject[i].ein);
            json_object_object_add(jobj, "einheit", ein);
            json_object *min = json_object_new_double(myobject[i].min);
            json_object_object_add(jobj, "min", min);
            json_object *max = json_object_new_double(myobject[i].max);
            json_object_object_add(jobj, "max", max);
            //füge Json objekt dem json array hinzu
            json_object_array_add(myarray,jobj);
        }
        //mache JSON-Array zu String
        ret=(char*)json_object_to_json_string(myarray);
        return ret;
    }
    

    wies aussieht wird der speicher im get_data gemalloc()t... wie gebe ich den diesen Speicher wieder frei? mit free() ist mir ja klar, seh aber nicht durch an welchem punkt ich das free setzen muss.

    Falls ihr mehr Daten zu den JSON-Objekten braucht, ich verwende die json-c lib



  • Du rufst dauernd new_irgendwas in deiner JSON-Funktion auf, aber nie destroy_irgendwas.
    Und musst du das ganze mit C machen? In C++ gibt es so schöne Sachen, womit man sich die ganze Quälerei mit den Pointern sparen kann.



  • Danke für den Tipp.. Ich werde gleich Testen ob ich die erstellten JSON-Objekte wieder destroyen kann.

    Ich schreibe das ganze in C weil ich von C++ noch weniger Ahnung habe... hab vor 6Jahren mal C gelernt... es ist nicht mehr alles frisch in meinen grauen Zellen, aber immerhin. (c = noob, c++ = ober noob, c# & java = gut) 😉



  • Neben der JSON-Angelegenheit ist

    int set_msgvalues(char * myvalue){
        msgvalues = malloc(strlen(myvalue));
        msgvalues = myvalue;
        return 0;
    }
    
    int set_data(struct canobject * mydata){
        data = malloc(sizeof(mydata));
        data = mydata;
        return 0;
    }
    

    mit Sicherheit falsch. Du forderst Speicher an und verlierst ihn sofort wieder. Meintest du etwas in der Art:

    int set_data(struct canobject const * mydata){
        struct canobject *tmp = malloc(sizeof(struct canobject));
    
        if(!tmp) return -1; /* Fehlerfall */
    
        memcpy(tmp, mydata, sizeof(struct canobject));
        free(data);
        data = tmp;
    
        return 0;
    }
    

    ? (Dabei wird ausgenutzt, dass globale Variablen zunächst mit Null initialisiert werden und free(NULL); nichts macht)



  • das sollte eigentlich nur eine funktion sein um "sicher" in die globale variable zu schreiben... dachte das geht irgendwie so... naja hattw nur ein beispiel mit int im kopf

    int i;
    int schreibe_globalint(int myint){
        i = myint;
        return 0;
    }
    

    dachte dann aber weil ich struct und char * habe muss ich da noch speicher reservieren... habe ich wohl falsch gedacht oder gemacht 😉

    was macht deine variante genau? ich muss das mal testen.

    und zum zerstören der JSON objekte wurde ich auch noch nicht schlauer... naja sonst mach ich dann mal wieder n beginn bei null... aber mit c++



  • Wenn du fit in Java bist, würde ich das Programm darin schreiben. Ansonsten finde ich C++ wesentlich schmerzfreier als C. Auch sollte man mit C++ wesentlich besser zurecht kommen, wenn man aus der C#/Java-Ecke kommt.



  • Hey Leute!

    Ich konnte den Memory Leak eindeutig auf die JSON-Objekte zurückführen. Ich werde jetzt das Programm in c++ umschreiben um die JSON-Objekte mit new und delete zu steuern. Ich bekam diese Objekte mit malloc etc. leider nicht in den Griff.

    Noch wieso ich mit C/C++ prgrammiere: Es wurde leider so gewünscht.. ich hätte auch lieber in einer höheren Sprache programmiert 😉



  • Wenn du mit malloc/free Probleme hast, dann hilft dir new/delete auch nicht wirklich weiter. Ich dachte da eher an etwas smarteres, was dir die Probleme abnimmt und für dich das free/delete erledigt. Mit einem shared Pointer kannst du eigentlich so ziemlich alle Fälle erschlagen.


Log in to reply