Why am getting segfault while I am still able to access those location?

时间:2018-03-31 07:37:23

标签: c string pointers segmentation-fault reverse

I am trying to reverse a string in-place using two pointers to the same string. First one(char *p) points to the starting location of the string and second one(char *q) points to the ending location of the string. So when I tried to debug using gdb, I get am getting segmentation fault at line 16.

When I tried to print the values of *p and *q, it works fine. Why am I getting segfault while I'm still able to access those location?

Breakpoint 1, main () at reverse.c:16
16          *q = *p;
(gdb) print p
$1 = 0x5555555547e4 "hello"
(gdb) print q
$2 = 0x5555555547e8 "o"
(gdb) step

Program received signal SIGSEGV, Segmentation fault.
0x00005555555546db in main () at reverse.c:16
16          *q = *p;

The actual code of the program is

#include<stdio.h>

int main() {
    char *array = "hello";

    char *p=&array[0];// pointer to the first element

    // Make q point to last value of the array
    char *q = &array[0];
    while(*q) q++; 

    char temp;
    q--; // move left so that we don't point to `\0`
    while(p<q){ 
        temp = *p;
        *q = *p;
        *p = temp; 
        p++;q--;    
    }

    printf(" Done reversing \n");
}

2 个答案:

答案 0 :(得分:6)

你的字符串,你称之为array,实际上不是一个字符数组,而是一个字符串文字,根据平台的不同,它是不可写的。所以把它改成

char array[] = "Hello";

char *array = "string"char array[] = "string"之间存在差异。

  • char *array = "string""string"放入内存的只读部分,并使array指向它。因此,任何改变内存array内容的尝试都会导致seg错误(换句话说是非法的)。
  • char array[] = "string""string"放入内存的只读部分, 放入堆栈中新分配的内存{ {1}}指向。因此,对内存array进行更改是合法的。

您还可以查看this post

答案 1 :(得分:2)

您正在尝试更改字符串文字

char *array = "hello";
指针array指向

虽然在C(与C ++相反)中,字符串文字具有非常量字符阵列的类型,但您可能不会更改字符串文字。任何更改字符串文字的尝试都会导致未定义的行为。

您应该声明一个字符数组,用字符串文字初始化它。例如

char array[] = "hello";

这是一个示范程序。

#include <stdio.h>

int main(void) 
{
    char array[] = "hello";

    puts( array );

    char *q = array;
    while ( *q ) ++q;

    for ( char *p = array; p < --q; ++p )
    {
        char c = *p;
        *p = *q;
        *q = c;
    }

    puts( array );

    return 0;
}

它的输出是

hello
olleh

您的程序中交换字符的代码段也是错误的

    temp = *p;
    *q = *p;
    *p = temp; 

必须有

    temp = *p;
    *p = *q;
    *q = temp; 

由于变量temp仅在while循环中使用,因此其声明区域应受while循环的块范围限制。

while(p<q){ 
    char temp = *p;
    *p = *q;
    *q = temp; 
    p++;q--;    
}

考虑到根据C标准,没有参数的函数main应声明为

int main( void )