Speicherzugriffsfehler

D

djtraumwelt

Foren As
beim Aufruf von
Code:
sprintf(name,"Alex");
bekomme ich einen Speicherzugriffsfehler. name wurde initialisiert am anfang der funktion mittels
Code:
char name[100];
Ich bin überfragt!
 
Ich hatte dem Letzt auch ein Problem mit "Speicherzugriffsfehler".
Bei mir kamen diese allerdings beim compilieren eines Programms.
Ursache war, dass der RAM voll war?! Wieso auch immer.... Nach einem Neustart des Systems war der Fehler verschwunden...

Wobei ich bei einem "sprintf" bezweifle, dass es sooo viel RAM kostet.... Aber gib doch mal "free" ein und schau, wie viel RAM du noch frei hast...
 
[Wegzensiert] Du musst die Doku lesen. Dafür ist die da.

MfG, PyroPeter

EDIT: Und da mich grade Schuldgefühle plagen, hier der interessante Teil von printf(3):
int sprintf(char *str, const char *format, ...);

Tja, dann bin ich wohl ein Troll.
 
Zuletzt bearbeitet:
Wenn du nicht den ganzen source und die Vorgangsweise wie dus kompilierst und ausführst postest kommen wir nirgendwo hin.
 
Wenn du nicht den ganzen source und die Vorgangsweise wie dus kompilierst und ausführst postest kommen wir nirgendwo hin.

Stimmt, bei mir erzeugt das Programm
Code:
#include <stdio.h>
int main() {
    char name[100];
    sprintf(name, "Alex");

    return 0;
}
keinen Speicherzugriffsfehler, egal ob ich mit gcc oder icc kompiliere, und auch valgrind gibt keine Probleme aus.
 
Ich werd jetzt einmal raten und sagen, das buffer vermutlich nicht nullterminiert ist.

Dein Stil ist echt unangenehm zu lesen, nebenbei kannst du dir das ""%s"," im sprintf sparen und ich denk amal, wenn du snprintf mit einer längenbeschränkung reingeben würdest würds dir vermutlich nicht segfaulten, aber es stünde ein riesen haufen mist in deinem user name.

Du solltest dich aber langsam in einen debugger einlesen, schau dir gdb, ddd und nemiver an.
 
Code:
                } else if (buffer[0]=='N') {
                    printf("%s",buffer);
gibt ebenfalls einen Speicherzugriffsfehler. Scheinbar habe ich innerhalb des ifs keine weitere berechtigung aus buffer zu lesen. komisch nur dass es bei password einwandfrei funktioniert.
 
Code:
                    printf("%s",buffer);

printf gibt bei "%s" alles bis zum nächsten '\0' aus, wenn du einen nicht nullterminierten string hast liest er über die grenzen von buffer hinaus bis der kernel ihm auf die finger haut und ihn mit einem segfault abschießt, oder er doch irgendwo eine '\0' findet, das wär aber reiner zufall.
 
das programm springt erst an diese stelle, wenn er in der for schleife ein \n findet, welches er sofort in 0 wandelt. die ausgabe von
Code:
printf("servfunc: ID %d received: %s\r\n",id,buffer);
funktioniert fehlerfrei und ein paar zeilen später dann der segfault mit dem fast gleichen printf
 
das programm springt erst an diese stelle, wenn er in der for schleife ein \n findet, welches er sofort in 0 wandelt. die ausgabe von
Code:
printf("servfunc: ID %d received: %s\r\n",id,buffer);
funktioniert fehlerfrei und ein paar zeilen später dann der segfault mit dem fast gleichen printf

meinst du
Code:
[I]buffer[n]=[B]0[/B];[/I]
printf("servfunc: ID %d received: %s\r\n",id,buffer);

Wenn du einen Teil von buffer auf 0 setzt ist es auch 0 terminiert, wenn bei dir nicht "if (buffer[n]=='\n')" ist setzt du buffer[n] auch nicht auf 0 und deswegen ist buffer in dem fall auch nicht 0 terminiert.
 
wenn "if (buffer[n]=='\n')" nicht ist, dann springt er gar nicht an die stelle, wo auf buffer zugegriffen wird. es ist also unmöglich, dass er den code ausführt während buffer nicht nullterminiert ist.
 
Natürlich, wenn buffer[0]=='N' dann werden die '\n' gar nicht ersetzt vorm ausführen.
 
Hi,

ich hab grad mal in den Code reingeschnuppert, die Formatierung ist ja wirklich fuerchterlich. Formatierung ist bekanntlich Geschmacksache, aber der Code ist voellig unleserlich.

Code:
for (; n < trc; n++) if (buffer[n]=='\n') {
Das ist eins der abscheulichsten Dinge die ich jemals in freier Wildbahn gesehen habe, ich dachte solche Konstrukte gaebe es nur in Texten zu schlechtem Stil...

Du tust dir und anderen sicherlich einen Gefallen wenn du dir mal ein paar Stilrichtlinien durchliest und zu eigen machst. Optimalerweise benutzt man dann noch einen Editor der die Formatierung automatisiert, in Eclipse z.B. mit ctrl-shift-F zu erreichen. Die Chance ist gross dass du dadurch automatisch zu einem besseren Programmierer wirst, mal davon abgesehen dass du leichter und schneller Hilfe bekommst.

Wie marcellus ja schon sagte, duerftest du den Fehlern mit einem Debugger am schnellsten auf die Schliche kommen, gerade protection faults wegen fehlender '\0' sind so leicht gefunden.

mfg,
bytepool
 
marcellus: die abfrage ob buffer[0] == 'N' ist, ist innerhalb des if (buffer[n]=='\n') gefolgt von einem buffer[n]=0

bytepool: hast du links zu "guter stil mit c", "stilrichtlinien in c" oder dergleichen? dann les ich mir alles durch und versuche mit einem guten stil das ganze programm nochmal komplett neu zu schreiben.
 
bytepool: hast du links zu "guter stil mit c", "stilrichtlinien in c" oder dergleichen? dann les ich mir alles durch und versuche mit einem guten stil das ganze programm nochmal komplett neu zu schreiben.

Ich denk dabei gehts eher um die Formatierung, als referenz kannst du dir ja http://www.gnu.org/prep/standards/standards.html#Writing-C anschauen

marcellus: die abfrage ob buffer[0] == 'N' ist, ist innerhalb des if (buffer[n]=='\n') gefolgt von einem buffer[n]=0
ist es nicht, wenn du es sauber formatiert hättest würdest dus auch leichter sehen


Code:
for (; n < trc; n++)
{
        if (buffer[n]=='\n')
        {  
                buffer[n]=0;
                printf("servfunc: ID %d received: %s\r\n",id,buffer);
                if (buffer[0]=='P') 
                {  
                        sprintf(password,"%s",&buffer[2]);
                }  
        }  
        else
        {  
                if (buffer[0]=='N') 
                {  
                        printf("Sax\r\n");
                        sprintf(user[id],"%s",&buffer[2]);
                        printf("servfunk: ID %d user[id] set to %s",id,user[id]);
                        for (a=0; a < strlen(user[id]); a++) 
                        {  
                                x=0;
                                for(b=0; b < strlen(allowed); b++)
                                {  
                                        if (user[id][a]==allowed[b])
                                        {  
                                                x=1;
                                                break;
                                        }  
                                }  
                                if (x==0)
                                {  
                                        user[id][a]='.';
                                }  
                        }  
                }
        }
}

Das sind 37 zeilen, in deiner formatierung warens 13 aber mit der formatierung sieht man wohl das es fälle gibt, wo buffer nicht nullterminiert ist.

ich hab übrigens nur die Klammern dort gesetzt wo sie der compiler auch gesetzt hätte. Aber hier noch mal das Original zum Vergleich. Schönheit liegt im Auge des betrachters aber ich denk das du mir zustimmen wirst, das die obere Variante leichter zu lesen ist.

Code:
for (; n < trc; n++) if (buffer[n]=='\n') {
                buffer[n]=0;
                printf("servfunc: ID %d received: %s\r\n",id,buffer);
                if (buffer[0]=='P') {
                    sprintf(password,"%s",&buffer[2]);
                } else if (buffer[0]=='N') {
                    printf("Sax\r\n");
                    sprintf(user[id],"%s",&buffer[2]);
                    printf("servfunk: ID %d user[id] set to %s",id,user[id]);
                    for (a=0; a < strlen(user[id]); a++) {
                        x=0;
                        for(b=0; b < strlen(allowed); b++) if (user[id][a]==allowed[b]) { x=1; break; }
                        if (x==0) user[id][a]='.';
                    }
 
http://pastebin.org/721403
also, hier ist buffer aber nullterminiert. gleicher fehler:
Code:
servfunc: ID 0 starting
pingfunc: ID 0 starting
servfunc: ID 1 starting
pingfunc: ID 0 send ping
servfunc: ID 0 received: p
servfunc: ID 0 sent: t 47

servfunc: ID 0 received: P sax
Set password to saxservfunc: ID 0 received: N Alex
Segmentation fault
 
Du hältst dich wohl an diese hässliche Formatierung.

Das Programm sieht so aus, alsob es über Zeile 190 nicht drüberkommt, ich seh da aber im Moment keinen Fehler und die nächsten paar Zeilen danach auch nicht. Ehrlichgesagt will ich mir den Stil nicht mehr geben als es sein muss.

Kompilier das programm mit "-O0 -g" wirfs im gdb an und post einen backtrace ( http://www.acm.uiuc.edu/sigmil/talks/gdb/gdb-intro.html )
Code:
gdb BINARYNAME
> run (COMMANDLINE PARAMETER HIER)
servfunc: ID 0 starting
pingfunc: ID 0 starting
servfunc: ID 1 starting
pingfunc: ID 0 send ping
servfunc: ID 0 received: p
servfunc: ID 0 sent: t 47

servfunc: ID 0 received: P sax
Set password to saxservfunc: ID 0 received: N Alex
Segmentation fault
> backtrace
Was da rauskommt will ich sehen
 
Code:
(gdb) run
Starting program: /home/alex/imserv
[Thread debugging using libthread_db enabled]
[New Thread 0xb7da1ad0 (LWP 6694)]
[New Thread 0xb7da0b90 (LWP 6697)]
servfunc: ID 0 starting
[New Thread 0xb75a0b90 (LWP 6698)]
[New Thread 0xb6da0b90 (LWP 6699)]
servfunc: ID 1 starting
[New Thread 0xb65a0b90 (LWP 6700)]
pingfunc: ID 0 starting
pingfunc: ID 0 send ping
servfunc: ID 0 received: p
servfunc: ID 0 sent: t 48

pingfunc: ID 0 send ping
servfunc: ID 0 received: p
servfunc: ID 0 sent: t 47

servfunc: ID 0 received: P sax
Set password to saxservfunc: ID 0 received: N Alex

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb7da0b90 (LWP 6697)]
0xb7dfe131 in fwrite () from /lib/libc.so.6
(gdb) backtrace
#0  0xb7dfe131 in fwrite () from /lib/libc.so.6
#1  0x080497c1 in parseit (buffer=0xb7d9e3ac "N Alex", id=0) at imserv.c:228
#2  0x08049273 in servfunk (arg=0x805a008) at imserv.c:161
#3  0xb7ee5f3b in start_thread () from /lib/libpthread.so.0
#4  0xb7e6cd0e in clone () from /lib/libc.so.6
 
Dein Fehler tritt in Zeile 228 auf und so betrachtet ist das auch kein Wunder. Du solltest echt sauberer formatieren.

Code:
fp=fopen(datei,"r");
if (fp)  
{
  ...
}
else
{
    fp=fopen(datei,"w");
    fwrite(password,1,strlen
Angenommen der lesezugriff scheitert nicht weil kein file da ist, sondern weil:
  • es gibt kein Verzeichnis names "./pws/"
  • du hast keine Schreibrechte ins Verzeichnis
  • das File ist schon zum schreiben geöffnet
  • das blockdevice ist ro gemountet
  • böse trolle wollen nicht, das du drauf zugreifst
Dann würd dein Programm beinhart mit einem Segfault abrauchen. Sowas gehört übrigens auch zu einem guten Programmierstil.
 

Ähnliche Themen

Kernel Kaltstart / reboot?

SELinux und IPTV

Unix Webserver mit HTML Seite erstellen

Freie Software auf dem Smartphone

Samba Datentransfer bricht ab

Zurück
Oben