【问题标题】:Why am getting segfault while I am still able to access those location? [duplicate]为什么在我仍然能够访问这些位置时出现段错误? [复制]
【发布时间】:2018-09-10 03:29:12
【问题描述】:

我正在尝试使用两个指向同一字符串的指针就地反转字符串。第一个(char *p) 指向字符串的起始位置,第二个(char *q) 指向字符串的结束位置。因此,当我尝试使用 gdb 进行调试时,我在第 16 行遇到了分段错误。

当我尝试打印*p*q 的值时,它工作正常。为什么我仍然可以访问这些位置时出现段错误?

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;

程序的实际代码是

#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");
}

【问题讨论】:

  • 与您的问题无关,但应该是temp = *q,您现在有temp=*p 和后来的*p=temp,什么都不做
  • 您遇到了段错误,因为您正在尝试写入只读内存。

标签: c string pointers segmentation-fault reverse


【解决方案1】:

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

char array[] = "Hello";

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

  • char *array = "string""string" 放入内存的只读 部分,并使array 指向它。因此,任何更改array 指向的内存内容的尝试都将导致段错误(换句话说,非法)。
  • char array[] = "string""string" 放入内存的只读 部分,并将其复制array 指向的堆栈上新分配的内存。因此,更改内存array 是合法的。

您可能还想看看this post

【讨论】:

    【解决方案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
    

    你的程序中交换字符的代码 sn-p 也是错误的

        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 )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-22
      • 2023-02-08
      • 2019-09-17
      • 1970-01-01
      • 2011-12-29
      • 2014-07-18
      • 1970-01-01
      • 2013-01-29
      相关资源
      最近更新 更多