以下内容摘自林锐博士的《高质量的C-C++编程》。虽然网上对这本书(文章?)的评价不高,但是个人觉得,内存管理这章还是有些地方可以借鉴的。因此,摘录这些内容算是一个复习和总结吧!
1指针与数组的对比
1.1修改内容
char a[] = "Hello";
a[0] = ‘X’; //OK
char *p = "Hello";
p[0] = 'X'; //error
指针p是指向常量字符串(位于静态存储区)。但是常量字符串的内容是不能改变的。所以当试图通过p[0]去改变时,会出错。并且编译的时候是没法发现该问题的。
1.2计算内容存储量
char a[] = "Hello World"; //sizeof(a) = 12
char *p = a; // sizeof(p) = 4
void Func(char a[100])
{
//sizeof (a)= 4
}
注意sizeof(p)得到的是一个指针变量的字节数。相当于sizeof(char *),而不是p所指向的内存的容量。c++是没有办法知道指针所指向内存的容量的,除非在申请的时候记住。
另外数组作为函数参数时,自动退化为同类型指针。
2.指针参数传递内存
void GetMemory(char *p, int size)
{
p = (char*)malloc(sizeof(char)*size);
}
void Test()
{
char *str =NULL;
GetMemory(str, 100); //str仍然是null
strcpy(str, "Hello");//错误
}
编译器总是会为函数的每个参数制作一个临时副本。指针参数p的副本是_p。编译器使_p=p。
如果函数内改变了_p所指向内存的内容。则p的内容也改变。这就是指针可以用作输出参数的原因。
但是本例中,为_p申请了新的内存。改变的只是_p的值,但是p未变化。所以调用GetMemory(...)之后,
str仍然是null。
可以通过如下方法改变内存。
char* GetMemroy(int size)
{
char *p= NULL;
p = (char*)malloc(sizeof(char)*size);
return p;
}
用函数返回值来传递动态内存这种方法虽然不错,但是要避免返回栈指针--函数结束的时候,栈内存自动销毁。
char *GetString()
{
char p[] = "hello World";
return p;
}
void Test()
{
char *str = NULL;
str = GetString(); //str的内容不确定
}