2013-02-09 96 views
0
int main() 
    { 
     char *ch="girl"; 
     int x=strlen(ch); 
     *ch=ch[x]; 
     printf("%c",*ch); 
     getch(); 
     return 0; 
    } 

为NULL指向字符的指针时,为什么会出现运行时错误?指针和字符串

+6

它是未定义的行为来修改字符串文字。 – 2013-02-09 12:53:45

+1

如果你想要打印字符串的最后一个字符,你应该把'* ch = ch [x]'改成'* ch = ch [x-1]' – 2013-02-09 12:54:23

+0

考虑在这种情况下使用'const' ..当声明它作为一个'const',你会得到一个'编译错误',这比'运行时错误'更好**。 – Maroun 2013-02-09 13:16:03

回答

1

UPDATE:感谢@dreamlax

"girl"被隐含声明为char *。但是很可能你的编译器会把字符串放到一个部分(rostrings)中,这些部分稍后会被放置在受保护的存储区域中。当你尝试分配*ch的东西时,它会访问这个受保护的(或不依赖于你的平台)内存。

编译器应警告您有关char *ch = "girl";

+1

“女孩”的类型是char [5]而不是'const char *'。 – dreamlax 2013-02-09 12:59:12

+0

那么为什么iam因为处于边界之内而出现运行时错误? – 2013-02-09 13:01:24

+0

因为您的平台将字符串文字放在受保护/只读内存中。 – 2013-02-09 13:03:07

-1

int x=strlen(ch); //x=4 
*ch=ch[x]; //you are out of bounds of array, because first element is 0, so last is 3 
+4

没有数组,它是一个字符串字面值,'ch [strlen(ch)]'不超出范围:它在最后引用零字节。 – 2013-02-09 12:56:41

2

更换

char *ch = "girl" 

char ch[] = "girl" 

其中前者创建一个指向不可变的存储器,后者创建了一个char[]数组大小合适的和用“女孩”的字母(包括终止零字节)初始化它。

+0

所以,如果我只是声明为char * ch,它会被内部视为一个字符的常量指针吗? – 2013-02-09 13:12:27

+1

我想你在问什么'char * ch =“girl”'的意思。指针的类型为'char *',因此如果尝试通过它修改数据,则不会出现编译时错误。但是在运行时,如果您这样做并且指针不指向可变内存,则它是未定义的行为。就像'ch'为NULL或指向释放内存一样。 – 2013-02-09 13:16:51

+0

我可以得到一个更具体的答案,为什么创建一个指针会使内存不可变,而不是数组? – 2013-02-09 13:28:01