使用指针修改字符串时发生分段错误?

bri*_*ice 10 c string reverse pointers

上下文

我正在学习C,我正在尝试使用指针来反转字符串.(我知道你可以使用一个数组;这更多的是关于学习指针.)

问题

尝试运行下面的代码时,我不断遇到分段错误.海湾合作委员会似乎不喜欢这*end = *begin;条线.这是为什么?

特别是因为我的代码几乎与另一个问题中讨论的非邪恶C函数相同

#include <stdio.h>
#include <string.h>

void my_strrev(char* begin){
    char temp;
    char* end;
    end = begin + strlen(begin) - 1;

    while(end>begin){
        temp = *end;
        *end = *begin;
        *begin = temp;
        end--;
        begin++;
    }
}

main(){
    char *string = "foobar";
    my_strrev(string);
    printf("%s", string);
}
Run Code Online (Sandbox Code Playgroud)

Rem*_*o.D 20

传递给函数的参数存在一个问题:

char *string = "foobar";
Run Code Online (Sandbox Code Playgroud)

这是在只读部分中分配的静态字符串.当您尝试用它覆盖它时

*end = *begin;
Run Code Online (Sandbox Code Playgroud)

你会得到段错误.

试试吧

char string[] = "foobar";
Run Code Online (Sandbox Code Playgroud)

你应该注意到一个区别.

关键点在于,在第一种情况下,字符串存在于只读段中,并且仅使用指向它的指针,而在第二种情况下,在堆栈上保留具有适当大小的字符数组和静态字符串(其中永远存在)被复制到其中.之后,您可以自由修改数组的内容.

  • 为了完全清楚,`char*s ="blah"`在5个字符的位置分配存储,可能是也可能不是只读的.在大多数情况下,存储器位于存储器的只读段中,旁边是程序指令的机器代码.另一方面,`char s [] ="blah";`在堆栈上分配一个可修改的5个字符的数组(即本地存储).这总是可以修改的.有关文字字符串的更多详细信息,请查看(http://stackoverflow.com/questions/2036096/literal-string-initializer-for-a-character-array). (2认同)

use*_*694 5

您还可以使用字符串末尾的空字符来交换字符串中的字符,从而避免使用任何额外的空格.这是代码:

#include <stdio.h>

void reverse(char *str){    
    int length=0,i=0;

    while(str[i++]!='\0')
        length++;

    for(i=0;i<length/2;i++){
        str[length]=str[i];
        str[i]=str[length-i-1];
        str[length-i-1]=str[length];
    }

    str[length]='\0';
}

int main(int argc, char *argv[]){

    reverse(argv[1]);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)