简体   繁体   English

c程序中的分段错误

[英]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: 但当我在ubuntu 10.04下运行我的“gcc”编译器时,我得到了:

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. 修饰字符串文字的内容(即代码中的“Hello World”)是未定义的行为。

ISO C99 (Section 6.4.5/6) ISO C99(第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 也会调用未定义的行为,因为您正在尝试释放尚未使用malloc分配的内存部分(使用free

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). 因为char *p = "Hello world"几乎肯定会给你一个指向只读内存的指针,这意味着尝试用*(p+1) = 'l'来改变它是一个肯定的禁忌(即使内存不是只读的,行为仍未定义)。

The relevant part of C99 referring to string literals is in 6.4.5 para 6 : C99中涉及字符串文字的相关部分见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. 是因为,即使您正在分配允许修改的内存,第二个语句也会将指针更改为指向字符串文字(当您失去对已分配内存的访问权限时会导致mmory泄漏),这不是允许修改。

You need to differentiate changes to the pointer from changes to what the pointer points at. 您需要区分对指针的更改以及指针指向的更改

"Hello world" is a string literal . "Hello world"是一个字符串文字 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. char *p指向那个字节块。 *(p+1) = 'l' says to overwrite the next byte after the pointed-at one with an 'l'. *(p+1) = 'l'表示用指向的*(p+1) = '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"; 为了具有在存储器中的文本可以被修改的副本,把它放到一个数组,例如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.) (请注意,声明数组这样使得它究竟大到足以容纳字符串,因此,你可能不会延长它,因为没有更多的空间。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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