1 #include <iostream> 2 using namespace std; 3 4 int main() 5 { 6 char *p[] = {"one","two","three"}; 7 cout<<*(p+2)<<endl; 8 cout<<sizeof(*(p+2))<<endl; 9 cout<<**(p+2)<<endl; 10 cout<<sizeof(**(p+2))<<endl; 11 12 return 0; 13 }
执行结果:
相当于有两层指针,数组名是一个指针,数组中每个元素又是char *类型
*(p+2)本身也是个指针(是一重指针),故大小为4。**(p+2)就是第一个元素了(char类型)故大小为1
char *p="abcd";
在C语言里,输出一个字符串的指针很方便,直接printf("%p/n",p);就输出了。
而C++里cout太自作聪明了,为了省去我们循环输出字符的麻烦,cout<<p<<endl;被翻译为输出p指向的字符串值。
char *q = "hello"; cout<<q<<endl; //输出hello cout<<*q<<endl; //输出h cout<<*(q+2)<<endl; //输出l
char *赋值问题
1 #include <iostream> 2 using namespace std; 3 4 class A 5 { 6 public: 7 A(char *str); 8 ~A(); 9 void print(); 10 private: 11 char *m_pData; 12 }; 13 14 A::A(char *str) 15 { 16 m_pData = new char[strlen(str) + 1]; 17 strcpy_s(m_pData, strlen(str) + 1, str); 18 } 19 20 A::~A() 21 { 22 delete [] m_pData; 23 } 24 25 void A::print() 26 { 27 cout << m_pData << endl; 28 } 29 30 int main() 31 { 32 A a("hello"); 33 a.print(); 34 35 system("pause"); 36 return 0; 37 }
delete和free之后设为NULL
引入:运行Test函数会有什么样的结果
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <cstring> 4 5 void Test() 6 { 7 char *str = (char *)malloc(100); 8 strcpy_s(str, strlen("hello") + 1, "hello"); 9 free(str); 10 11 if (str != NULL) 12 { 13 strcpy_s(str, strlen("world") + 1, "world"); 14 printf(str); 15 } 16 } 17 18 int main() 19 { 20 Test(); 21 system("pause"); 22 return 0; 23 }
以上程序在vs2013运行正常,输入world。但是程序篡改了动态内存区的内容,后果难以预料。
因为free(str)之后,会让str指向内存中的内容清空,但并不意味着str == NULL,所以仍然走if中的条件,然后str就是野指针了。
指针free之后,free函数只是把指针指向的内存空间释放了,即内存中存储的值,但是并没有将指针的值赋为NULL,指针仍然指向这块内存。而程序判断一个指针是否合法,通常都是使用if语句测试该指针是否为NULL来判断,导致指针成为所谓的“野指针”,诱导误操作,
“野指针”与空指针不同,“野指针”有地址,或者说指向指定的内存,对野指针进行操作很容易造成内存错误,破坏程序数据等危险。“野指针”无法简单地通过if语句判断其是否为 NULL来避免,而只能通过养成良好的编程习惯来尽力减少,free函数执行后,一定要接着设置指针为NULL。