使用ARM,C编译器,我可以成功编译并运行以下命令:
static char * myString = 0;
void myfunc(int x){
if (x <= 0)
myString = "Hello World";
else
myString = "This is a different string with a different length";
}
int main(){
myfunc(-1);
printf("%s\n", myString);
myfunc(2);
printf("%s\n", myString);
}
为什么这样做?
指针不应该是NULL指针吗?
至少,不应该在只读内存位置分配字符串文字吗?
编辑:它是一个C ++编译器
EDIT2:为什么在myfunc超出范围后,字符串文字存在于静态范围内?字符串文字是否未在堆栈中声明?他们什么时候被解除分配?
谢谢!
答案 0 :(得分:7)
两个字符串在只读存储器中分配,完全不同。但是你用一个相同的指针指向它们中的每一个......有什么不明白的?
请记住,char*
只是一个指针。它是可变的(非常数)。
char* p = 0;
p = "Hello"; //OK
p = "Jo" //OK;
p[0] = 'X' //OOPS, now THIS is bad (undefined behavior)
编辑后:
不,字符串文字具有静态存储持续时间(与所有其他文字不同),它们不是在堆栈上创建的。它们将存在直到程序终止。
答案 1 :(得分:3)
如果您要声明
char const *MyString = 0;
然后你会遇到麻烦,因为const指针无法重新分配。字符串文字是常量。
.section .rodata
.LC0:
.string "Hello World"
.align 8
.LC1:
.string "This is a different string with a different length"
.text
文字字符串数据汇编在只读数据部分。
答案 2 :(得分:2)
常量字符串通常在程序的“数据段”中创建,并且指向它们的指针始终有效(字符串“对象”对程序生命周期有效)。所以不行。文字字符串不是在堆栈上创建的。
我相当肯定语义在C中是明确定义的。
快乐的编码。
答案 3 :(得分:1)
它是,但是你为它指定了一个指向字符串文字的指针,所以它指向两个字符串数组中的一个。
答案 4 :(得分:0)
最初它是一个空指针。但是你自己明确地改变了那个指针并使它在myfunc
函数内变为非空。
在第一次调用myfunc
时,您明确地将指针指向字符串文字"Hello World"
。在那之后,指针当然不再为空。
字符串文字确实分配在只读内存位置(至少在概念上)。但是,在C和C ++中,您可以使用char *
指针指向字符串文字(即不需要const char *
)。只要你没有尝试修改文字就可以指向到带有char *
指针的字符串文字。您的代码不会尝试修改任何内容,所以没关系。
C和C ++中的字符串文字具有静态存储持续时间。所以不,他们没有被“分配”。它们总是分配在静态内存中,这意味着它们永远存在 - 只要程序正在运行。
P.S。为了更完整地回答您的问题,您必须解释为什么地球上您希望指针保持为空。
P.P.S。 int main
,而非void main
。
答案 5 :(得分:0)
myString
是一个指针变量,你故意将它设置为指向存储两个字符串常量之一的内存。