2017-11-10 112 views
-4

我是C的开端,所以请忍受我; 我知道我可以做一个数组声明*cc[];关于Memset的简单问题C

我的问题是关于memset的:

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

工作正常。 但是:

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

不工作, 我知道字符*str = ...是一个正常的数组声明。

如果任何人都可以帮助我这个我谢谢!

+0

你的问题会在你遇到指针和数组时回答你很多问题。考虑像按值复制或按指针复制(引用其他人称它的方式)。这里有两个相同的概念。 ''char str [] =“hello”;''表示你在该数组中做了一个字面字符串'hello'的拷贝,你可以在那里操作那个字符串,但是当你做'char * str =“hello”;'你现在处理的是一个指向这个Literal字符串的指针,在'C'中你读/访问它们,但是你不能写/编辑它们。希望你现在了解差异。 – Michi

+0

* c不是数组语句。 – Fredrik

回答

5

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

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

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


现代计算机有一个复杂的内存布局,和一整套的概念,你需要学会在某些时候,如Virtual MemoryPaging 以及诸如StackHeap

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

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

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

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

在第1例的实际阵列被分配在堆栈上,并充满包含"hello!\0"(7字节)的字节。该内存可以被操作,因为它在分配在可写页面上的堆栈上。

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

它的工作,因为str是数组,其内容可以修改,因为本地数组存储在内存,我们可以修改堆栈段

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

它不工作,因为str为指针STR本身存储在堆栈部分,但指向代码(只读)在Linux的情况下,内存部分。所以你试图修改只读内存,这就是为什么它不会工作。

+0

我想说'str'字符指针在第二种情况下,它的代码段的地址初始化,修改代码段将产生访问冲突。这是错的吗 ? – achal

+0

好男人非常感谢你的快速重新申请,抱歉它重复我的坏,上帝保佑你们; – Mondometal