我已经定义了一个函数,它有一个指向char的指针作为它的参数。将常量字符串传递给此函数的指针时,字符串是否在内存中保留了专用空间,或者任何其他对象都可以覆盖它而不使用指针访问此指定空间?
定义我的功能
void myFunction(char *p){
// some instructions
}
将常量字符串传递给此函数
myFunction("Some Text");
答案 0 :(得分:4)
你应该写void myFunction(const char *p){
,无论你做什么,都不要试图修改p 指向的字符串。要这样做是未定义的行为。
这是因为字符串"Some Text"
将在程序编译时被复制到只读内存中,指向该字符串的指针将传递给p
。
答案 1 :(得分:2)
该调用将字符串文字的地址传递给函数,并且该地址在编译时(或程序启动时动态链接的时间)固定,但从这个问题的角度来看,它是相同的)。如果某些东西试图修改该内存地址的内容,则依赖于操作系统会发生什么。在许多(大多数?全部?)现代PC操作系统中,字符串文字将位于只读存储区中,如果应用程序尝试修改它,则会出现分段错误。在其他(较旧的,嵌入式的等)操作系统或CPU架构中,甚至可能没有办法使某些内存成为只读,然后可以修改字符串文字,但它仍可能导致意外结果(参见下一段) )。 修改字符串文字是C标准中的未定义行为。
记忆是“专注的”是解释的问题。如果您有两个字符串文字,如"foobar"
和"bar"
,则允许编译器使它们重叠,因此"foobar"
字面指向'f',而"bar"
字面点到'b'在同一个内存空间。除非你正在做一些非常“聪明”的指针比较,否则这应该没有区别,因为它们都在只读内存中。
在某些方面可以修改字符串:可以编写以内核权限运行的代码,这可以在程序运行时修改“只读”内存的内容。也可以更改编译器,使字符串文字不在只读内存中,然后可以修改它们而不会导致程序崩溃。对于非运行时永久更改,可以使用十六进制编辑器简单地编辑程序二进制文件并更改字符串。但在进行常规应用程序开发时,这些都不是问题。
一般来说,如果你在C语言中传递指向函数的指针(或C ++,这也适用于引用),总是使它成为指向const(或C ++中的const引用)的指针,如const char*
in这个案例。调用者可能有一个const对象,并且您不希望阻止它们使用该对象调用该函数。如果函数实际上要修改参数,那么您希望编译器停止调用者将const对象传递给它。
答案 2 :(得分:1)
是的,它确实在内存中保留了专用空间。 没有其他对象可以覆盖它而不使用指针来访问这个指定的空间。
答案 3 :(得分:0)
不,它没有为字符串分配内存,指向字符串开头的指针被推入堆栈,如果你试图修改字符串,你会发生段错误,你可以修改指针。 / p>