C中关于Memset的简单问题[重复]

Posted

技术标签:

【中文标题】C中关于Memset的简单问题[重复]【英文标题】:Simple matter about Memset in C [duplicate] 【发布时间】:2017-11-10 23:03:52 【问题描述】:

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

我的问题是关于 memset:

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

工作正常。 但是:

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

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

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

【问题讨论】:

当涉及到指针和数组时,您的问题会回答很多其他人。考虑诸如按值复制或按指针复制之类的事情(参考其他人如何称呼它)。同样的概念在这里发生了两次。 char str[] = "hello"; 意味着您在该数组中复制文字字符串 hello,您可以在其中操作该字符串,但是当您执行 char *str = "hello"; 时,您现在处理一个指向该文字字符串并在 @ 987654329@ 您可以阅读/访问它们,但不能编写/编辑它们。希望您现在了解其中的区别。 *c 不是数组语句。 【参考方案1】:

这里的区别很微妙 - 它是存储字符串的位置。

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

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


现代计算机具有复杂的内存布局,以及一整套您需要在某个时候学习的概念,例如 Virtual Memory 和 Paging 比如Stack和Heap。

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

第二个示例中的文字字符串“hello”分配在 const 段 (.rodata) 中,因此无法更改。此外,如果你定义几个这样的字符串

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

s1 == s2 很可能为真(地址比较!)

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

【讨论】:

【参考方案2】:
char str[] = "hello!";
  memset (str,'-',2);
  puts (str);

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

但是

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

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

【讨论】:

我想说'str'在第二种情况下是一个字符指针,它用代码段地址初始化,修改代码段会导致访问冲突。错了吗? 好的,伙计们非常感谢您的快速回复,对不起,这是重复我的错,上帝保佑你们;

以上是关于C中关于Memset的简单问题[重复]的主要内容,如果未能解决你的问题,请参考以下文章

用于长(64位)类型的C ++ memset()[重复]

C中memset的行为[重复]

如何使用 memset 清除 char 数组 [重复]

C分配双精度的动态数组并用memset初始化它[重复]

memset显示错误的结果[重复]

C++ memset 是不是仅适用于 0 和 -1? [关闭]