2011-03-17 101 views
3

使用的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已超出范围后?字符串文字是否未在堆栈中声明?何时它们被释放?

谢谢!

+1

你能澄清你的问题吗? “myString”不再为NULL的原因是您已分配给它。 – 2011-03-17 17:04:49

+0

请参阅EDIT2。感谢大家。 – 2011-03-17 17:06:48

+0

文字可能分配在只读存储器中。第一个的形式类型是'const char [12]'。你可以将它的地址分配给一个'char *',因为它只允许在C中使用。为了正确,你应该使用'const char *'。 – 2011-03-17 17:12:10

回答

7

这两个字符串被分配在只读存储器中,并且完全不同。但是你用同一个指针来指向它们中的每一个......有什么不明白的?

请记住,char*只是一个指针。它是可变的(非const)。

char* p = 0; 
p = "Hello"; //OK 
p = "Jo" //OK; 
p[0] = 'X' //OOPS, now THIS is bad (undefined behavior) 

您的编辑后:

没有,字符串具有静态存储时间(不像其他所有文字),他们不是在堆栈中创建。它们将存在直到程序终止。

+0

请参阅有问题的edit2。谢谢阿门。 – 2011-03-17 17:08:36

+0

@J T:查看我的编辑 – 2011-03-17 17:09:58

+1

这里存在未定义的行为,因为C兼容性损害了const的正确性。在虚构的类型安全世界中,将字符串文字分配给char *将是编译时常量违例。 – 2011-03-17 17:24:16

1

这是,但是你分配一个指向字符串的指针,所以它指向两个字符串数组中的一个。

0

最初它是一个空指针。但是你自己明确地改变了这个指针,并且在myfunc函数中使它变为非null。

在第一次拨打myfunc时,您明确地将您的指针指向字符串字面值"Hello World"。在那一刻之后,指针当然不再为空。

字符串文字确实分配在只读内存位置(至少在概念上)。但是,在C和C++中,都允许您使用char *指针指向字符串文字(即不需要const char *)。只要指向就可以将字符串与char *指针串起来,只要你不试图修改文字即可。你的代码不会尝试修改任何东西,所以它没问题。

C和C++中的字符串文字具有静态存储持续时间。所以不,他们没有被分配到“堆栈”上。它们总是被分配在静态存储器中,这意味着它们永远活着 - 只要你的程序正在运行。

P.S.为了更全面地回答你的问题,你必须解释你为什么在地球上期望你的指针保持为空。

P.P.S. int main,而不是void main

0

myString是一个指针变量,你故意将它设置为指向存储你的两个字符串常量之一的内存。

3

如果你申报

char const *MyString = 0; 

那么你会遇到麻烦的常量指针不能被重新分配。字符串文字是常量。

 .section  .rodata 
.LC0: 
     .string "Hello World" 
     .align 8 
.LC1: 
     .string "This is a different string with a different length" 
     .text 

字符串数据在只读数据部分组装。

2

通常在程序的“数据段”中创建常量字符串,并且指向它们的指针始终有效(字符串“objects”对程序生存期有效)。所以不行。字符串不会在堆栈上创建。

我相当肯定C中的语义是明确定义的。

快乐编码。