当前位置:   article > 正文

c 语言中对字符串常量修改的错误原因解析

c 语言中对字符串常量修改的错误原因解析

字符串常量进行修改

#include <stdio.h>
int main()
{
    char *a = "hello";	// 字符串常量
    a[0] = 'w';
    printf("%s\n", a); 
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

运行以上代码会出现如下错误: Segmentation fault,即段错误。

错误解析

将上述代码编译成汇编代码如下。从中可以看出,字符串常量被声明在 rodata 节,即只读数据节(read only data)。因此尝试对字符串修改,即会引发段错误。

    .section    .rodata			; 只读数据节开始
.LC0:
    .string "hello"				; 声明的字符串常量 char *a = "hello";
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $20, %esp
    movl    $.LC0, -12(%ebp)
    movl    -12(%ebp), %eax
    movb    $119, (%eax)		; 尝试对字符串修改 a[0] = 'w';
    subl    $12, %esp
    pushl   -12(%ebp)
    call    puts
    addl    $16, %esp
    movl    $0, %eax
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

对字符串数组进行修改

include <stdio.h>
int main()
{
    char a[]="hello";
    a[0] = 'w';
    printf("%s\n", a); 
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

将其编译成汇编如下,可以看出,字符串被拷贝到堆栈上,因此对其修改没有问题。

main:
    pushl   %ebp
    movl    %esp, %ebp
    movl    $1819043176, -18(%ebp)				;	$ebp-18 = "hell"
    movw    $111, -14(%ebp)						; 	$ebp-14 = "o\0"
    movb    $119, -18(%ebp)						; 	a[0] = 'w';
    subl    $12, %esp
    leal    -18(%ebp), %eax
    pushl   %eax
    call    puts
    addl    $16, %esp
    movl    $0, %eax
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/319541
推荐阅读
相关标签
  

闽ICP备14008679号