c - 奇怪的段错误(数组和指针之间的区别?)

标签 c segmentation-fault

我不明白为什么我会从这段代码中得到段错误,并且当我使用数组而不是指针时它会起作用,如果有人能让我理解这一点,我会很高兴。

void main() {
   char *str = "example string";
   wrapChrInStr(str, 'a');
}

void wrapChrInStr(char *str, unsigned char chr) {
   char *ptr = str;
   char c;

   while((c = *ptr)) {
       if(c != chr) {
           *str = c;
           str++;
           ptr++;
       } else {
           ptr++;
       }
   }
   *str = '\0';
}

最佳答案

Thank you. I'm doing a lot of c programming and its really weird that i never faced that before.

可能是因为您没有意识到有不同的存储方式 C 弦。您可能很幸运,从未遇到过段错误 因为这个。

字符串文字

字符串文字用双引号声明,例如

"hello world"

该字符串通常存储在只读部分中。使用字符串时 文字,最好使用 const 声明变量,如下所示:

const char *str = "hello world";

有了这个,您就知道 str 指向只读内存位置,并且您不能 操作字符串的内容。事实上,如果你这样做:

const char *str = "hello world";
str[0] = 'H';
// or the equivalent
*str = 'H'

编译器将返回如下错误:

a.c:5:5: error: assignment of read-only location ‘*str’

我发现这非常有帮助,因为你不能意外地操纵 str指向的内容。

数组

如果你需要操作字符串的内容,那么你需要存储 数组中的字符串,例如

char str[] = "hello word";

在这种情况下,编译器知道字符串文字有 10 个字符,并为 str 和保留 11 个字节('\0' 为 1 个字节 - 终止字节)初始化数组 字符串文字的内容。

在这里你可以做类似的事情

str[0] = 'H'

但您无法访问超过第 11 个字节的内容。

您还可以声明一个固定大小的数组。在这种情况下,尺寸必须是 至少与字符串文字的长度+1相同。

char str[11] = "Hello world";

如果您声明较少的空间(例如char str[3] = "hello world";), 你的编译器会警告你类似这样的内容

a.c:4:14: warning: initializer-string for array of chars is too long

但我不确定如果你执行代码会发生什么。我认为这是未定义行为的情况 这意味着:任何事情都有可能发生。

就我个人而言,我通常声明我的字符串没有固定大小,除非有 具有固定大小的原因。

关于c - 奇怪的段错误(数组和指针之间的区别?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55291177/

相关文章:

C - 需要检测数字中是否存在数字(hw)

c - 使用 GMP 从公式计算非常大的整数

c - 为什么在执行 strcpy 时出现段错误?

c++ - 同名结构,不同定义 : segmentation fault with -O2

在 C 中创建具有邻接矩阵的图

c - 如何使用 fopen() 选择打开模式?

c++ - 访问指向结构中的值是否比访问本地值花费更多时间?

c - Linux 内核中的 tty_tiocmset 屏蔽所需的调制解调器信号

c - 使用 getline() 输入时出现段错误

c - 使用 malloc 时 C 中的奇怪段错误