微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Linux上用C语言中的char数组和指针分割错误

所以我有以下程序:

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

它在“one [1] ='b'”这一行上进行段错误,这是合理的,因为指针“one”指向的内存必须位于只读内存中。 然而,问题是为什么不行“two [1] ='b'”段错误? 查看gcc的汇编输出

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

我们看到两个string都在rodata部分,所以它们是只读的。 那么怎么会这样“two [1] ='b'这段代码没有段错?

SSB dbgen Linux – 分段错误

从未定义长度的文件中读取,存储在数组中,分段错误

获取分段错误或崩溃的指令指针(对于x86 JIT编译器项目)?

为什么glibc的fclose(NULL)会导致分段错误而不是返回错误

SIGSEGV进入函数

在fortran程序中访问数组时发生分段错误

C常量全局内存段错误(在地址上存在)

x86 GNU汇编奇怪的更改Seg错误

“无法解释”核心转储

MysqL_stmt_close时出现Segfault错误

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

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

你在rodata部分看到的“另一个”是当它被初始化的时候,在数组two被复制的东西。 另一方面,字符串“computer”的地址将被分配给一个

所以, one是指向一个只读段(因此在写入segfault),而two将被分配在堆栈,然后“另一个”将被复制到它。

第二种形式通过复制文字字符串来创建一个数组。

这相当于:

char two[] = {'a','n','o','t','h'. 'e',r',''};

您可以使用变量初始化字符数组,如

char c = 'a'; char two[] = {'a',c,''};

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐