C a SIGSEGV při dereferencování

asd

C a SIGSEGV při dereferencování
« kdy: 18. 01. 2013, 16:08:13 »
Caute. Mam takyto kod:

Kód: [Vybrat]
    1 #include <stdio.h>
    2 #include <ctype.h>
    3
    4 void strtoupper(char *str)
    5 {   
    6     while (*str) // na znaku \0 sa cyklus zastavi
    7     {   
    8         *str = toupper(*str); // dereferencuje aktualny znak na ktory ukazuje str, zavola toupper a nahradi tento znak
    9         str++; // posunie ukazatel o 1
   10     }
   11 }
   12
   13 int main()
   14 {   
   15     char *str = "hello world";
   16     strtoupper(str);
   17 
   18     printf("%s\n", str);
   19 
   20     return 0;
   21 }

a pada mi to hned pri prvom prechode cyklom:
Kód: [Vybrat]
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400571 in strtoupper (str=0x40066c "hello world") at case.c:8
8 *str = toupper(*str);
« Poslední změna: 18. 01. 2013, 16:16:27 od Petr Krčmář »


pipipi

Re:C a SIGSEGV při dereferencování
« Odpověď #1 kdy: 18. 01. 2013, 16:28:09 »
protoze
char *str = "hello world";
je read only

char str[] = "hello world";
bude ok

pipipi

Re:C a SIGSEGV při dereferencování
« Odpověď #2 kdy: 18. 01. 2013, 16:37:28 »

Re:C a SIGSEGV při dereferencování
« Odpověď #3 kdy: 18. 01. 2013, 16:41:28 »
char str[] = "hello world";
bude ok
Nebude. Je to uplne stejna chyba.

pipipi

Re:C a SIGSEGV při dereferencování
« Odpověď #4 kdy: 18. 01. 2013, 16:47:04 »
tomu nerozumim, proc?

char str[] = "hello world";
je snad uplne totez co
char str[12] = "hello world";

no a tohle uz mi snad prekladac nekde doprcic neda


DarkKnight

Re:C a SIGSEGV při dereferencování
« Odpověď #5 kdy: 18. 01. 2013, 16:54:01 »
char str[] = "hello world";
bude ok
Nebude. Je to uplne stejna chyba.

Ale bude, je rozdil mezi char * x  a char x[]
pokud to chce resit pres char * x, musi nejdrive naalokovat pamet a pak to tam nakopirovat

Re:C a SIGSEGV při dereferencování
« Odpověď #6 kdy: 18. 01. 2013, 17:04:02 »
Ale bude, je rozdil mezi char * x  a char x[]
No mas pravdu, funguje to stejne jako = {'a','b',0}. To je az desivy, jak clovek rychle zapomina :(

pipipi

Re:C a SIGSEGV při dereferencování
« Odpověď #7 kdy: 18. 01. 2013, 17:05:55 »
mimochodem

int main() {   
     char str[] = "hello world";
     puts(str); 
     return 0;
 }


prelozi gcc jako
main:
    pushl   %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $32, %esp
    leal    20(%esp), %eax
    movl    %eax, (%esp)
    movl    $1819043176, 20(%esp)
    movl    $1870078063, 24(%esp)
    movl    $6581362, 28(%esp)
    call    puts
    xorl    %eax, %eax
    leave
    ret


takze tam skutecne vytvari na zasobniku lokalni promennou, a pak do ni cpe ten string
1819043176 = 0x6c6c6568 = "lleh"
1870078063 = 0x6f77206f = "ow o"
6581362 = 0x646c72 = "\0dlr"

takze toto proste musi fungovat, pokud to teda neni tak nejak platformove zavisle

Re:C a SIGSEGV při dereferencování
« Odpověď #8 kdy: 18. 01. 2013, 17:16:59 »
prelozi gcc jako
Z toho, jak co gcc prelozi, bych asi radsi zadne zavery nevyvozoval :)

Ale kazdopadne jsi mel pravdu, standard to rika jasne: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf str. 144, example 8

Za zapomenuti takhle zakladni veci se asi dneska budu cervenat az do pulnoci :))

asd

Re:C a SIGSEGV při dereferencování
« Odpověď #9 kdy: 18. 01. 2013, 17:19:25 »
Dakujem vsetkym za odpovede/prispevky  :)

pipipi

Re:C a SIGSEGV při dereferencování
« Odpověď #10 kdy: 18. 01. 2013, 17:28:41 »
no ja to gcc uvedl spis jako zajimavost, jak to pak vypada, kdyz uz jsem to zkousel
tak jsme si aspon trochu zopakovali C ;)