为啥指向 char 的指针与指向 char 作为数组元素的指针的行为不同?
Posted
技术标签:
【中文标题】为啥指向 char 的指针与指向 char 作为数组元素的指针的行为不同?【英文标题】:why is pointer to a char behaving differently than a pointer to a char as array element?为什么指向 char 的指针与指向 char 作为数组元素的指针的行为不同? 【发布时间】:2017-10-09 08:51:55 【问题描述】:我很好奇为什么这两段代码给出不同的输出
#include <iostream>
using namespace std;
int main()
char *arr=new char;
arr="monday";
cout<<arr<<endl;//gives the output "monday"
char *newArr=new char[3];//i want array of three pointers not the size of a string to be 2+1
newArr[0]="monday";//err
cout<<newArr[0]<<endl;
system("pause");
return 0;
我的意思是他们不是都指向首字母地址的指针
问题是“arr”和“newArr[0]”有什么区别
【问题讨论】:
【参考方案1】:你遇到的麻烦比你意识到的要多......
有
char *arr=new char;
arr="monday";
您首先让arr
指向您分配的单个 字符。然后你重新分配arr
并使它指向其他地方(指向文字"monday"
的数组的第一个字符)。这会导致泄漏,因为您分配的原始内存丢失并且无法再访问。
至于
char *newArr=new char[3];
newArr[0]="monday";
这里你让newArr
指向一个由三个单字符组成的“数组”,然后尝试让单字符newArr[0]
指向字符串字面量。
有点不同,你想做什么
char* arr = new char;
基本上等价于
char arr[1];
还有
char* newArr = new char[3];
相当于
char newArr[3];
标准解决问题的方法当然是使用 C++ 标准 std::string
类。比如说
std::string arr;
arr = "monday";
再加上第二个std::vector
或std::array
:
std::array<std::string, 3> newArr;
newArr[0] = "monday";
最后,关于arr
和newArr[0]
的区别。一个是指向char
的指针,类型为char*
。另一个是char
(但newArr
是指向char
的指针,就像arr
)。
【讨论】:
如果我可以问,为什么编译器甚至允许重新分配 arr @awashima 因为它不是无效的?如果你愿意,你可以让它指向任何地方。 C++不牵你的手,如果你想shoot yourself in the foot你可以做到。【参考方案2】:它们不是都指向首字母地址的指针吗?
是的,arr
和 newArr
都是指向 C 样式字符串中初始字符的指针。但是,newArr[0]
根本不是指针,因此 C++ 不允许您为其分配 const char*
指针。
如果要获取指向newArr
的首字符的指针,需要使用运算符&
,即&newArr[0]
。您将无法分配它,但您可以打印它:
const char *newArr = "monday";
cout << newArr[0] << endl; // prints m
cout << &newArr[0] << endl; // prints monday
请注意,代码中new
的两个赋值都会产生内存泄漏,因为你用另一个值覆盖了new
产生的值,而没有释放分配的内存。
【讨论】:
删除arr;删除 [] newArr;应该加吗? @awashima 如果您的代码以任何方式使用分配的值,这将是正确的。但是,它不会:您立即覆盖分配的指针。这就是为什么更好的选择是完全删除new
,因为您的程序不使用它的结果。
好的,我明白了,我只想要两个,在我看来语义相同的代码块......但如果我做这样的事情(分配是动态分配数组并填充它一周中的天数) char (*arr)[12]=new char[7][12]; strcpy(arr[0],"星期一"); strcpy(arr[1],"星期二"); strcpy(arr[2],"星期三"); strcpy(arr[3],"星期四"); strcpy(arr[4],"星期五"); strcpy(arr[5],"星期六"); strcpy(arr[6],"星期日"); for(int i=0;i
@awashima 您评论中的代码是正确的,它没有内存泄漏。【参考方案3】:
“arr”和“newArr[0]”有什么区别
简短的回答,与arr
不同,newArr[0]
不是指针,而是可以容纳一个字符。 newArr[i]
与 *(newArr + i)
相同。您正在尝试将字符串放置到字符类型上。
【讨论】:
以上是关于为啥指向 char 的指针与指向 char 作为数组元素的指针的行为不同?的主要内容,如果未能解决你的问题,请参考以下文章
为啥新的 Visual Studio 将字符串文字作为指向常量的指针?
在 C# String 构造函数 String(Char*) 中,为啥构造函数不期望指向字符数组的指针?
指向 char 指针数组的指针与指向 char 指针的指针(或 char** argv 与 char* (*argv)[])