通过替换字符串的字母在 C 中出现分段错误

segmentation fault in C by replacing a string's letter

我想替换字符串中的一个字符(例如第二个字符)。 我的代码有什么问题?它可以编译,但它没有执行我需要的操作,而是给我一个分段错误。谢谢!

#define _XOPEN_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <cs50.h>
#include <string.h>

int main (int argc, string argv[])
{
    string key="abcd";
    key[1]='f';
}

编译我的代码后

~/workspace/pset2/crack/ $ clang -ggdb3 -O0 -std=c11 -Wall -Werror -Wshadow bug.c -lcrypt -lcs50 -lm -o bug
~/workspace/pset2/crack/ $ ./bug
Segmentation fault
string key="abcd";

string 基本上是 char *key 是字符串文字。您尝试修改它,因此出现分段错误。

我没有看到名称 string 的定义,但我认为它类似于 char *

因此在这个声明中

 string key="abcd";

声明了一个指向字符串文字的指针。

字符串文字在 C 中是未修改的,任何修改字符串文字的尝试都会导致未定义的行为。

来自 C 标准(6.4.5 字符串文字)

7 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.

您只能修改堆或堆栈中的内存,您的 "abcd" 有所谓的字符串文字,属于程序的只读内存 space,它不能在它所在的位置进行修改(无论如何,如果它是 运行 在任何体面的操作系统下)。

一开始就放在那里的原因是因为 string 基本上只是一个 char * 指针,它会指向任何内存 space 并且不关心它是否是只读 space 与否。 (不要与 C++ std::string 混淆)。

要使其可修改,您必须告诉 C 它不是指针,而是数组。

char key[] = "abcd";

现在C会把这个字符串放入栈中,你可以随意修改。

这是因为 "abcd" 并未真正复制到您的 key 变量中。 相反,key 是指向此常量字符串的指针。

如果你想修改它,你可以这样做:

int main (int argc, string argv[])
{
    char key[] = { "some string" };
    key[1]='f';
}