C中关于Memset的简单问题[重复]
Posted
技术标签:
【中文标题】C中关于Memset的简单问题[重复]【英文标题】:Simple matter about Memset in C [duplicate] 【发布时间】:2017-11-10 23:03:52 【问题描述】:我是 C 的初学者,所以请多多包涵;
我知道我可以将数组语句设为*c
或c[]
;
我的问题是关于 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的简单问题[重复]的主要内容,如果未能解决你的问题,请参考以下文章