Linux 上 C 中字符数组和指针的分段错误 [英] Segmentation Fault With Char Array and Pointer in C on Linux

查看:24
本文介绍了Linux 上 C 中字符数组和指针的分段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有以下程序:

int main(){
  char* one = "computer";
  char two[] = "another";
  two[1]='b';
  one[1]='b';
  return 0;
}

它在 "one[1]='b'" 行上出现段错误,这是有道理的,因为指针 "one" 指向的内存必须在只读内存中.但是,问题是为什么two[1]='b'"行没有段错误?查看 gcc 的程序集输出:

It segfaults on the line "one[1]='b'" which makes sense because the memory that the pointer "one" points to must be in read only memory. However, the question is why doesn't the line "two[1]='b'" segfault? Looking at the assembly output from gcc:

.file   "one.c"
        .section        .rodata
.LC0:
        .string "computer"
.LC1:
        .string "another"
        .text
.globl main
        .type   main, @function
main:

我们看到两个字符串都在rodata 部分,所以它们是只读的.那么two[1]='b'"这行怎么没有段错误呢?

We see that both strings are in the rodata section so they are readonly. So then how come the line "two[1]='b' does not segfault?

推荐答案

one 直接指向位于只读页面中的字符串.另一方面,two 是分配在堆栈上的数组,并使用一些常量数据进行初始化.在运行时,可执行文件的只读部分中的字符串将被复制到堆栈中.您正在修改的是堆栈上该字符串的副本,而不是只读内存页面.

one points directly to the string located in a read-only page. On the other hand, two is an array allocated on the stack and is initialized with some constant data. At run time, the string in the read only section of the executable will be copied to the stack. What you are modifying is the copy of that string on the stack, not the read-only memory page.

从更高层次的角度来看,从语言的角度来看,"abcd"const char* 类型的表达式,而不是 char*.因此,修改此类表达式所指向的值会导致未定义的行为.语句 char* one = "something"; 仅将指向字符串的指针存储在变量中(不安全,因为它正在丢弃 const 修饰符).char two[] = "something"; 完全不同.它实际上是声明一个数组并对其进行初始化,很像 int a[] = {1,2,3};.这里引号中的字符串是初始化表达式.

At a higher level perspective, from the language point of view, "abcd" is an expression of type const char* and not char*. Thus, modifying the value pointed by such an expression results in undefined behavior. The statement char* one = "something"; merely stores the pointer to the string in a variable (unsafely, since it's casting away const modifier). The char two[] = "something"; is totally different. It's actually declaring an array and initializing it, much like int a[] = {1,2,3};. The string in quotes here is the initialization expression.

这篇关于Linux 上 C 中字符数组和指针的分段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆