strncat oder strcat in funktion bringen Speicherüberlauf

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
chris_1981_
Beiträge: 72
Registriert: Sa Jun 15, 2013 8:41 pm

strncat oder strcat in funktion bringen Speicherüberlauf

Beitrag von chris_1981_ » Sa Jun 15, 2013 9:07 pm

Hallo zusammen,

ich bin gerade dabei C zu lernen, habe 3 Bücher die ich nun nach und nach durchackere, aber ich habe jetzt schon ein Problem und würde gerne wissen, was passiert und warum ich in einen Speicherüberlauf komme.

Vorab, ich bin C Anfänger also erwartet nicht zuviel!

Code: Alles auswählen

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

typedef enum
{
    LOG_DEFAULT,
    LOG_INFO,
    LOG_ERROR,
    LOG_DEBUG
}LOG_LEVEL;

/**
        @brief  LOG-Messages for File Output
        @param  LOG_LEVEL, Message
        @return none
*/
void log_messages(LOG_LEVEL line, char *message)
{   
    // welche LOG_LEVEL
    // Linie wird ausgelesen
    printf ("%i \n", line);

    // haenge didel an char message 
    // ----> genau hier gibt es ein Problem <----
    strcat(message,"didel");

   // pruefe 
    if( (line==LOG_INFO) || (line==LOG_ERROR))
    {
        // gebe aus
        printf ("%s \n", message);
    }
}   

int main (void)
{
    // definiere einen zeiger
    int *f;
    
    // defeniere einen integer
    int f1 = 22;

    // uebergebe die speicherstelle
    f = &f1;
   
    // definiere eine character variable
    char neuchar[9] = "neuerwer";
    
    // definiere einen integer
    int one = 22;

    // definiere eine character variable
    char message[75] = "hallo Welt";

    // funktion per call by value
    log_messages(LOG_ERROR,"DIES IST EINE NACHRICHT!");

    // gebe die variable message aus
    printf("ENDE-> %s \n", message);
  
    // EXIT Status
    return 0;
}

Also ich habe hier einige Header Files die "noch" nicht notwendig sind.

Aber eher zu meiner Frage:
Warum bekomme ich einen

Code: Alles auswählen

Speicherzugriffsfehler (Speicherabzug geschrieben)
, wenn ich das Programm so übersetze? Lasse ich das STRCAT bzw. STRNCAT weg kann es ohne Probleme übersetzt werden.

Was habe ich denn da wieder einmal Falsch verstanden?

Vielen Dank fürs Lesen!

Benutzeravatar
darksider3
Beiträge: 347
Registriert: Fr Sep 14, 2012 6:26 pm
Wohnort: /dev/sda1
Kontaktdaten:

Re: strncat oder strcat in funktion bringen Speicherüberlauf

Beitrag von darksider3 » Sa Jun 15, 2013 9:22 pm

Willkommen im Forum!
Vorab, ich bin genauso anfänger in C/++! :)
Es liegt an der art und weise wie Du versuchst, den String zu übermitteln. Ich weiß nicht __genau__ wieso dass jetzt funktioniert, aber es Funzt^^

Code: Alles auswählen

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

typedef enum
{
    LOG_DEFAULT,
    LOG_INFO,
    LOG_ERROR,
    LOG_DEBUG
}LOG_LEVEL;

/**
        @brief  LOG-Messages for File Output
        @param  LOG_LEVEL, Message
        @return none
*/
void log_messages(LOG_LEVEL line, char *message)
{   
    // welche LOG_LEVEL
    // Linie wird ausgelesen
    printf ("%i \n", line);

    // haenge didel an char message
    // ----> genau hier gibt es ein Problem <----
    strcat(message,"doodle");

   // pruefe
    if( (line==LOG_INFO) || (line==LOG_ERROR))
    {
        // gebe aus
        printf ("%s \n", message);
    }
}   

int main (void)
{
    // definiere einen zeiger
    int *f;
   
    // defeniere einen integer
    int f1 = 22;

    // uebergebe die speicherstelle
    f = &f1;
   
    // definiere eine character variable
    char neuchar[9] = "neuerwer";
   
    // definiere einen integer
    int one = 22;

    // definiere eine character variable
    char message[75] = "hallo Welt";

    // funktion per call by value
    log_messages(LOG_ERROR, message);

    // gebe die variable message aus
    printf("ENDE-> %s \n", message);
 
    // EXIT Status
    return 0;
}

BTW ich hab nur den Aufruf der Funktion ändern müssen. Funktioniert so auch... ^^
effizienz ist, wenn ich ein loch bohre und hinterher mein nachbar auch ein bild aufhängen kann... ^^
Meine Homepage und der Microblog von mir :)
Live Life dont let Life Live You!
Am meisten Aktiv in Webentwicklung und PHP im Wiki

chris_1981_
Beiträge: 72
Registriert: Sa Jun 15, 2013 8:41 pm

Re: strncat oder strcat in funktion bringen Speicherüberlauf

Beitrag von chris_1981_ » Sa Jun 15, 2013 9:30 pm

Hallo darkseider3,

danke!

Das habe ich auch probiert, das es so funktioniert hätte ich schreiben sollen,
aber genau darum geht es ja, ich muss / will meine log_messages in meinem Script gerne so übergeben, sonst muss ich ja immer voher die Variable "message" definieren.

ich weiß, für log Nachrichten gibt es viele Libarys, ich will es aber gerne Lernen, anstatt nur abzuschreiben.

Vielen Dank!

Benutzeravatar
darksider3
Beiträge: 347
Registriert: Fr Sep 14, 2012 6:26 pm
Wohnort: /dev/sda1
Kontaktdaten:

Re: strncat oder strcat in funktion bringen Speicherüberlauf

Beitrag von darksider3 » Sa Jun 15, 2013 9:47 pm

Das habe ich auch probiert, das es so funktioniert hätte ich schreiben sollen,
aber genau darum geht es ja, ich muss / will meine log_messages in meinem Script gerne so übergeben, sonst muss ich ja immer voher die Variable "message" definieren.
Wäre hilfreich gewesen, stimmt schon^^
Da wird dir wohl jmd anders helfen müssen. Ich hatte mal eine Funktion in C++ geschrieben, welche char's zusammenfügt(Anhängt). Aber leider bist Du bei C, also hast Du kein "new"..
Sry, MFG
effizienz ist, wenn ich ein loch bohre und hinterher mein nachbar auch ein bild aufhängen kann... ^^
Meine Homepage und der Microblog von mir :)
Live Life dont let Life Live You!
Am meisten Aktiv in Webentwicklung und PHP im Wiki

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: strncat oder strcat in funktion bringen Speicherüberlauf

Beitrag von Xin » Sa Jun 15, 2013 11:05 pm

Moin Chris
chris_1981_ hat geschrieben:Aber eher zu meiner Frage:
Warum bekomme ich einen

Code: Alles auswählen

Speicherzugriffsfehler (Speicherabzug geschrieben)
, wenn ich das Programm so übersetze? Lasse ich das STRCAT bzw. STRNCAT weg kann es ohne Probleme übersetzt werden.

Was habe ich denn da wieder einmal Falsch verstanden?
In dem Programm stecken einige ... Missverständnisse.

Wenn Du einen C-String mit Anführungszeichen schreibst ("DIES IST EINE NACHRICHT") dann ist der C-String unveränderlich. Als Datentyp heißt das (char const *). Früher hat man das alles viel lockerer gesehen und dann stürzen Programme halt ab. Weil man das früher lockerer gesehen hat und man alte (funktionierende) Programme noch kompilieren möchte, kompiliert Dein Programm leider auch.

Die Signatur für "void log_messages(LOG_LEVEL line, char *message)" würde in C++ nicht kommentarlos kompilieren:

Code: Alles auswählen

apoc:Desktop xin$ g++ chris.c 
chris.c: In function ‘int main()’:
chris.c:58: warning: deprecated conversion from string constant to ‘char*’
[/quote]

Mit strcat fügst du dem ersten Argument - dem unveränderlichen C-String - etwas an. Da der unveränderlich ist... knallt's.

Du musst einen veränderlichen C-String übergeben, also ein Stück Speicher, was Du verändern darfst.
[code]
    char message2[200];
    strcpy( message2, "DIES IST EINE NACHRICHT!");
    // funktion per call by value
    log_messages(LOG_ERROR,message);
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

chris_1981_
Beiträge: 72
Registriert: Sa Jun 15, 2013 8:41 pm

Re: strncat oder strcat in funktion bringen Speicherüberlauf

Beitrag von chris_1981_ » So Jun 16, 2013 9:12 am

Hallo Xin,

danke für deine Antwort. Okay, dann schaue ich mir das Kapitel mit den veränderlichen und unveränderlichen Werten / Variablen nochmals an. Da ich eher aktuell in Perl und Python programmiere bzw. Scripte erzeuge, programmieren würde ich das noch lange nicht nennen, aber gerne in Zukunft "bessere" Codes für Microcontroller schreiben möchte und versuche Scripte von andere Sprachen zu portieren, lerne ich halte C.

Danke auch, dass du nicht die "Sau" rausgelassen hast "ala" : Mein Gott, liess das Buch und gehe uns nicht auf die Nerven!

Aber du hast geschrieben:
In dem Programm stecken einige ... Missverständnisse.
Da ich gerade am Lernen dieser Sprache bin, wäre es nett, wenn du mir mitteilen würdest, wo noch Missverständnisse auffallen, sollte es um Kommentare gehen, wie "deklarieren und definieren bitte ich um Entschuldigung, die Begriffe sind klar, aber ich vertausche Sie gerne.

Vielen Dank für die Zeit!

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: strncat oder strcat in funktion bringen Speicherüberlauf

Beitrag von Xin » So Jun 16, 2013 11:24 am

chris_1981_ hat geschrieben:Danke auch, dass du nicht die "Sau" rausgelassen hast "ala" : Mein Gott, liess das Buch und gehe uns nicht auf die Nerven!
In diesem Forum erwarte ich einen konstruktiven Ton. Du hast eine konstruktive Frage gestellt, die für eine Anfänger auch nicht unbedingt trivial ist. Entsprechend bekommst Du - wenn möglich - eine konstruktive Antwort, ansonsten bekommt derjenige einen auf den Deckel, der sich nicht konstruktiv verhalten hast.
chris_1981_ hat geschrieben:Da ich gerade am Lernen dieser Sprache bin, wäre es nett, wenn du mir mitteilen würdest, wo noch Missverständnisse auffallen, sollte es um Kommentare gehen, wie "deklarieren und definieren bitte ich um Entschuldigung, die Begriffe sind klar, aber ich vertausche Sie gerne.
Das Missverständnis vorrangig ist, dass es in C konstante Objekte gibt, aber C sich nicht übertrieben darum schert (C++ schon, daher solltest Du auch C-Codes eher mit C++ übersetzen). Mit modernen Betriebsystemen (so ab den 80ern) gibt es aber Speicherschutz, das heißt das Betriebsystem unterscheidet zwischen veränderlichen und konstanten Daten. Vorher konnte man nach belieben im Speicher rumschreiben, was gerade bei Multitasking zu heiteren Effekten führte, wenn Programm X fehlerhaft war und deswegen Programm Y abschmierte.
"HIER IST EINE MESSAGE" liegt im unveränderlichen Programmcode. Du willst mit strcat Text hinzufügen, das geht nicht. Nicht nur, weil kein Platz hinter "HIER IST EINE MESSAGE IST", den Du beschreiben dürftest, sondern auch, weil Du sowieso nicht schreiben darfst. Die Hardware verbietet Dir es - deswegen stürzt das Programm ab.

Wenn Du das C-Tutorial von proggen.org liest, sollte Dir das erklärt worden sein (unter Konstante Strangs). An der Qualität andere Quellen kann ich natürlich nichts ändern.
Schaust Du dann noch unter strcat stellst Du fest, dass der erste Parameter vom Datentyp (char *) ist und eben nicht von (char const *). Programmierst Du sauberes C (was einem Anfänger hier wirklich nicht offensichtlich ist), dann kann dieser Fehler nicht passieren, weil Du den (char const *)"DIES IST EINE MESSAGE" überhaupt nicht an die Funktion übergeben darfst, da es ja eben kein (char *) ist.

Fehler muss man machen, um sie zu verstehen. So lernt man programmieren. Und dafür ist die Seite da.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Antworten