我是C的前任,所以请耐心等待我;
我知道我可以将数组语句设为*c
或c[]
;
我的问题是关于memset:
char str[] = "hello!";
memset (str,'-',2);
puts (str);
工作正常。 但是:
char *str = "hello!";
memset (str,'-',2);
puts (str);
不工作,
我知道char *str = ...
是一个正常的数组语句。
如果有人可以帮我这个,我谢谢你!
答案 0 :(得分:5)
这里的区别很微妙 - 它是存储字符串的地方。
char str[] = "hello!";
在堆栈上分配一个字符串,可以更新。
char *str = "hello!";
在程序const数据段中分配一个字符串,并将str设置为指向该段。该段无法被操纵,并且您的程序因内存访问冲突而崩溃。
现代计算机具有复杂的内存布局,以及您需要在某些时候学习的一整套概念,例如Virtual Memory和Paging 例如Stack和Heap。
正在加载到内存中的程序被分段为不同的部分,这些部分被加载到具有不同权限的不同页面。代码和全局const变量被加载到没有写入权限(仅读取) - .text和.rodata段的页面 - 而堆栈和堆分配在可以写入但不能执行的页面上(.data和.bss)。
文字字符串"你好"在第二个例子中,在const段(.rodata)中分配,因此不能改变。而且,如果你定义了几个这样的字符串
char *s1 = "Hello!";
char *s2 = "Hello!";
s1 == s2
很可能是真的(地址比较!)
在第一个示例中,实际数组正在堆栈上分配,并填充包含"hello!\0"
(7个字节)的字节。可以操作该内存,因为它位于可写页面上的堆栈上。
答案 1 :(得分:0)
char str[] = "hello!";
memset (str,'-',2);
puts (str);
它正常工作,因为 str是数组并且您可以修改其内容,因为本地数组存储在我们可以修改的RAM的堆栈部分中。
,但
char *str = "hello!";
memset (str,'-',2); //
它不起作用,因为 str是指针而 str本身存储在堆栈部分,但指向RAM的代码(只读)部分 linux的情况。所以你试图修改只读内存,这就是为什么它不起作用。