查询指针解除引用

时间:2014-03-22 19:37:47

标签: c++ pointers

我正在做一些字符串操作并遇到问题。

 char *arr1 = "HELLO";
 (*arr1)++;

这会引发错误“访问违规写入位置”!

但是,下面的代码工作正常。

 char arr1[] = "HELLO";
 (*arr1)++;

什么是存储char * arr1和char arr1 []的内存段?

5 个答案:

答案 0 :(得分:2)

 char *arr1 = "HELLO";

上面的定义意味着arr1 的内存可以分配在内存的只读部分(实际上是实现定义的行为),因此可能导致'当您尝试更改内存位置的值时,“访问冲突”指向。

char arr1[] = "HELLO";

在这种情况下,arr1的内存在堆栈中分配 - 这是可写的。因此,表达式(*arr1)++可以正常运行。

答案 1 :(得分:0)

文字喜欢" HELLO"属于const char[]的类型衰减到const char*,编译器可以将它放在实际上无法修改的内存中,修改会导致未定义的行为。 g ++给出了如下警告:

main.cpp:7:14: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

 char *arr1 = "HELLO";

编译器允许这样做,因为你可以在这里阅读(http://en.cppreference.com/w/cpp/language/string_literal):

  

在C中,字符串文字的类型为char [],可以直接赋值   到(非常)char *。 C ++ 03也允许它(但不赞成使用它,   因为文字是C ++中的const)。 C ++ 11不再允许这样的分配   没有演员。

但实际上即使启用了C ++ 11,我也不会在g ++上出错。

数组当然可以修改,所以你的第二个例子工作正常。这段代码:

char arr1[] = "HELLO";

在堆栈上创建一个长度为6的数组,并使用" HELLO \ 0"进行初始化。

答案 2 :(得分:0)

在第一种情况下,arr1是一个局部变量,它保存一个指向包含字符串"HELLO"的只读内存段的指针。语句(*arr1)++尝试修改段的第一个字节(包含字符'H'),这会导致访问冲突。

在第二种情况下,arr1是一个局部变量,它包含一个由六个字节组成的数组,用{'H', 'E', 'L', 'L', 'O', 0}初始化。局部变量在读写存储器中,因此修改它们不会导致错误。

答案 3 :(得分:0)

没有指针算术。您正在为字符串的第一个字符添加一个。由于字符串常量不可写,因此第一个版本会出错。在第二个版本中,您更改了on char数组的内容,因此没有问题。

答案 4 :(得分:0)

您没有执行任何指针算法。你取消引用指针然后递增它指向的东西(第一个字符)。

不幸的是,无法修改字符串文字(并且您的编译器应该警告char*是坏的并且const char*是好的,指向字符串文字)。

它适用于第二种情况,因为从字符串文字初始化本地数组会创建您自己的数据副本。