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