C中Memset的简单问题

Simple matter about Memset in C

我是C的初学者,所以请多多包涵; 我知道我可以将数组语句设为 *cc[];

我的问题是关于 memset 的:

  char str[] = "hello!";
  memset (str,'-',2);
  puts (str);

工作正常。 但是:

char *str = "hello!";
  memset (str,'-',2);
  puts (str);

不工作, 我知道 char *str = ... 是一个普通的数组语句。

如果有人能帮我解决这个问题,谢谢!

这里的区别很微妙 - 这是存储字符串的地方。

char str[] = "hello!";在栈上分配一个字符串,可以更新

char *str = "hello!"; 在程序 const 数据段中分配一个字符串并将 str 设置为指向该段。该段无法操作,您的程序因内存访问冲突而崩溃。


现代计算机具有复杂的内存布局,并且在某些时候您需要学习一整套概念,例如 Virtual Memory and Paging 例如 Stack and Heap.

加载到内存中的程序被分成不同的部分,这些部分以不同的权限加载到不同的页面。代码和全局 const 变量被加载到没有写入权限(仅读取)的页面 - 分别是 .text 和 .rodata 段 - 而堆栈和堆分配在可以写入但不能执行的页面(。数据和.bss).

第二个例子中的文字串"hello"分配在常量段(.rodata)中,因此无法更改。此外,如果您定义多个这样的字符串

char *s1 = "Hello!";
char *s2 = "Hello!";

很有可能s1 == s2会是真的(地址比较!)

在第一个例子中,一个实际的数组被分配到堆栈上并填充了包含 "hello![=14=]"(7 个字节)的字节。该内存可以被操作,因为它位于分配给可写页面的堆栈上。

char str[] = "hello!";
  memset (str,'-',2);
  puts (str);

它可以工作,因为 str 是数组 并且您可以修改它的内容,因为本地数组存储在 RAM 的 堆栈部分 中,我们可以修改.

但是

char *str = "hello!";
  memset (str,'-',2); //

它不起作用,因为 str 是指针 并且 str 本身存储在堆栈 部分,但 指向代码(读取仅)在 linux 的情况下 RAM 的部分 。所以你试图修改只读内存,这就是它不起作用的原因。