【问题标题】:Strings using char pointers使用 char 指针的字符串
【发布时间】:2018-01-25 18:34:56
【问题描述】:
#include<stdio.h>
 int main(void)
 {
   char s='a',*j;
   j=&s;
   *j='b';
   printf("s is %c",s);
 }

输出: s 是 b。

从这个程序我们得到,我们可以通过改变指针的值来改变分配给常量 char 的值。

但以下程序不会发生这种情况。

#include<stdio.h>
int main(void)
{
  char *p="Hello";
  *p='z';   //By assuming that it should change 'H' as *p points to address of H//
  printf("%c",*p);
}

输出:Segmentation Fault Core dumped

即使在这种情况下,Hello 中第 0 个字符的值也不应该在我们操作它的指针时发生变化,*p 是否指向 H 地址处的值。此处预期的输出是否应该是“zello”。

【问题讨论】:

  • 您正在尝试更改字符串文字。这有着悠久的历史。在许多较旧的 c 编译器中,这是错误地允许的。出于向后兼容性的原因,某些编译器仍将允许它。但显然你的不是

标签: c string pointers char


【解决方案1】:

从这个程序我们得到,我们可以通过改变指针的值来改变分配给常量 char 的值。

您的第一个 sn-p 中没有“常量字符”。它只是一个用某个值初始化的char 类型的变量。它被分配在RW内存中,因此您可以获取它的地址并修改内容。

在第二个 sn-p 中,您定义了一个 pointer 并为它分配一个 string literaladdress,它被分配在一个不应该写入的内存(通常是只读的,或者只是写入它的未定义行为)。

【讨论】:

  • +1 我什至看到它偶尔会起作用,所以它可能非常不可预测。我会假设文字被放在 .data 部分并且可能应该是只读的,但我猜优化编译器可能会做出其他决定。
  • @Patrick87 我想他们会被放入.rodata。但它可能不会被强制为只读。此外,我相信存在使字符串文字可写的扩展。但是 UB 可能来自不同的其他事物,例如仅分配一个“Hello”用于初始化不同的指针和/或将此文字传递给函数。所以在一个地方修改它会导致一些非常有趣的东西。
  • 字符串文字和字符数组之间的实际区别是什么?
  • @DevashishDewalkar 您可以将字符串文字视为位于只读内存中的字符数组。也看看我年轻时问过的question :)
  • @EugeneSh。字符串文字的内存是在可执行文件的.rodata 部分中创建的,并且是只读的(只是为了澄清措辞)您可以使用gcc -S -masm=intel -o file.asm file.c 确认,您会在@987654327 之前找到.section .rodata @
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-19
  • 2010-12-12
  • 2021-04-15
  • 1970-01-01
  • 2021-03-30
  • 2019-01-15
  • 1970-01-01
相关资源
最近更新 更多