简体   繁体   中英

segmentation fault in c program

just for testing i had created the following code:

#include<stdio.h>

int main(){
    char *p = "Hello world";
    *(p+1) = 'l';
    printf("%s", p);
    return 0;
}

But when i ran this over my "gcc" compiler under ubuntu 10.04 I got:

Segmentation fault

So can anyone explain this why this happened.

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

int main(){
    char *p = malloc(sizeof(char)*100);
    p = "Hello world";
    *(p+1) = 'l';
    printf("%s", p);
    free(p);
    return 0;
}

this also cause a segmentation fault Thanks in Advance

char *p = "Hello world"; *(p+1) = 'l';

Modiying the content of a string literal (ie "Hello World" in your code) is Undefined Behavior.

ISO C99 (Section 6.4.5/6)

It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined .

Try using array of characters.

char p[] = "Hello World";
p[1] = 'l'; 

EDIT

Your modified code

#include<stdio.h>
#include<stdlib.h>
int main()
{
   char *p = malloc(sizeof(char)*100);
   p = "Hello world"; // p now points to the string literal, access to the dynamically allocated memory is lost.
   *(p+1) = 'l'; // UB as said before edits
   printf("%s", p);
   free(p); //disaster
   return 0;
}

invokes Undefined Behaviour as well because you are trying to deallocate the section of memory (using free ) which has not been allocated using malloc

Because char *p = "Hello world" has almost certainly given you a pointer to read-only memory and that means that trying to change it with *(p+1) = 'l' is a definite no-no (even if the memory isn't read-only, the behaviour is still undefined).

The relevant part of C99 referring to string literals is in 6.4.5 para 6 :

It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.


The reason why you still get a segmentation fault with something like:

char *p = malloc (100);  // sizeof(char) is ALWAYS 1
p = "Hello";             // better would be: strcpy (p, "Hello")
*p = 'a';

is because, even though you're allocating memory which you're allowed to modify, the second statement changes the pointer to point to a string literal (giving you a mmory leak as you lose access to the allocated memory), which you are not allowed to modify.

You need to differentiate changes to the pointer from changes to what the pointer points at.

"Hello world" is a string literal . It is represented by a chunk of bytes in a region of memory which may not be modified . char *p points at that chunk of bytes. *(p+1) = 'l' says to overwrite the next byte after the pointed-at one with an 'l'. The next byte after the pointed-at one is part of the chunk which may not be modified. Attempting to overwrite something is attempting to modify it. Attempting to modify something which is not allowed to be modified is very bad.

In order to have a copy of the text in memory which may be modified, put it into an array, eg char p[] = "Hello world"; . (Notice that declaring the array this way makes it exactly big enough to hold the string, and therefore you may not lengthen it, since there is no more room.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM