宝杉的博客

UNIX/LINUX;ACE;SNMP;C++
posts - 33, comments - 23, trackbacks - 0, articles - 0

指针与数组

Posted on 2007-08-03 13:08 宝杉 阅读(190) 评论(0)  编辑 收藏 引用 所属分类: C++

数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。数组名对应着(而不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变。

指针可以随时指向任意类型的内存块,它的特征是“可变”,所以我们常用指针来操作动态内存。指针远比数组灵活,但也更危险。

1 修改内容

       char a[] = "hello";

       a[0] = 'X';

       cout << a << endl;

       char *p = "world";     // 注意p指向常量字符串

       p[0] = 'X';                 // 编译器不能发现该错误

       cout << p << endl;


2 复制与比较

strcpy(new type[strlen(a)+1]),而不能用p = a    //把a的地址给了p,而不是a的内容

strcmp(if strcmp(a,p)== 0),而不能用      if( a = p)  

       // 数组…

       char a[] = "hello";

       char b[10];

       strcpy(b, a);                 // 不能用       b = a;

       if(strcmp(b, a) == 0)     // 不能用  if (b == a)

       // 指针…

       int len = strlen(a);

       char *p = (char *)malloc(sizeof(char)*(len+1));

       strcpy(p,a);                  // 不要用 p = a;

       if(strcmp(p, a) == 0)     // 不要用 if (p == a)

sizeof内存容量计算

1           sizeof(p)相当于sizeof(char*),C++不支持对指针所指内容容量的计算。

char a[] = "hello world";

    char *p  = a;

    cout<< sizeof(a) << endl;   // 12字节

    cout<< sizeof(p) << endl;   // 4字节

2           数组作为函数参数,退化成同类型指针。

void Func(char a[100])

    {

        cout<< sizeof(a) << endl;   // 4字节而不是100字节

}

指针参数传递内存

首先,考虑函数为参数创建临时副本的问题。对于值传递,有形参和实参的区别。但对于引用和指针传递,则可能会产生问题。

 

指针作为函数参数,不能动态申请内存。

void GetMemory(char *p, int num)

{

       p = (char *)malloc(sizeof(char) * num);

}

void Test(void)

{

       char *str = NULL;

       GetMemory(str, 100);           // str 仍然为 NULL     

       strcpy(str, "hello");               // 运行错误

}

毛病出在函数GetMemory中。编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是 _p,编译器使 _p = p。如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改。这就是指针可以用作输出参数的原因。在本例中,_p申请了新的内存,只是把_p所指的内存地址改变了,但是p丝毫未变。所以函数GetMemory并不能输出任何东西。事实上,每执行一次GetMemory就会泄露一块内存,因为没有用free释放内存。

如何改正:

1 用“指向指针的指针”

void GetMemory2(char **p, int num)          //**p

{

       *p = (char *)malloc(sizeof(char) * num);

}

void Test2(void)

{

       char *str = NULL;

       GetMemory2(&str, 100);                    // 注意参数是 &str,而不是str

       strcpy(str, "hello");

       cout<< str << endl;

       free(str);

}

2 用函数返回值来传递动态内存

char *GetMemory3(int num)

{

       char *p = (char *)malloc(sizeof(char) * num);

       return p;

}

void Test3(void)

{

       char *str = NULL;

       str = GetMemory3(100);      

       strcpy(str, "hello");

       cout<< str << endl;

       free(str);

}

注意

强调不要用return语句返回指向“栈内存”的指针

char *GetString(void)

{

       char p[] = "hello world";

       return p;  // 编译器将提出警告

}

void Test4(void)

{

char *str = NULL;

str = GetString();   // str 的内容是垃圾

cout<< str << endl;

}


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理