关于C中Memset的简单问题

-4 c memset

我是C的前任,所以请耐心等待我; 我知道我可以将数组语句作为*cc[];

我的问题是关于memset:

  char str[] = "hello!";
  memset (str,'-',2);
  puts (str);
Run Code Online (Sandbox Code Playgroud)

工作良好.但:

char *str = "hello!";
  memset (str,'-',2);
  puts (str);
Run Code Online (Sandbox Code Playgroud)

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

如果有人可以帮我这个,我谢谢你!

imm*_*tal 5

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

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

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


现代计算机具有复杂的内存布局,以及您需要在某些时候学习的一整套概念,例如虚拟内存分页, 以及堆栈.

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

第二个示例中的文字字符串"hello"在const段(.rodata)中分配,因此不能更改.而且,如果你定义了几个这样的字符串

char *s1 = "Hello!";
char *s2 = "Hello!";
Run Code Online (Sandbox Code Playgroud)

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

在第一个例子中,实际数组正在堆栈上分配,并填充包含"hello!\0"(7字节)的字节.可以操作该内存,因为它位于可写页面上的堆栈上.