游戏开发论坛

 找回密码
 立即注册
搜索
查看: 5051|回复: 7

对于new char[0]又研究了一下

[复制链接]

6

主题

65

帖子

67

积分

注册会员

Rank: 2

积分
67
发表于 2007-10-27 13:28:00 | 显示全部楼层 |阅读模式
char *p = new char[0]能够返回一个有效的地址指针。
但对于它的用途不是很清楚,中午研究了一下它的内存读写特性。
发现通过p读后面的内存空间不会有问题,但不能超过进程边界。
但如果通过p写后面的地址空间,哪怕是p[0],delete []p时就会发生异常。
下面是实验过程和分析:

#include <iostream>
using namespace std;

void main()
{
        char *p = new char[0];
       
        //用p读取p后面的内存没问题,但读出来的结果没有意义
        cout << "the address pointed by p is " << (void *)p << endl;
        cout << "p[0] is " <<p[0]<<endl;
        cout << "p[1] is " <<p[1] << endl;
        cout << "... ..." << endl;
        cout << "p[50] is " <<p[50] << endl;
        cout << "... ..." << endl;
        cout << "p[100] is " <<p[100] <<endl;
        //多于5103就不行了。
        cout << "p[5103] is " << p[5103] <<endl;
       
        //用p也可以写p后面的内存,但释放p时就会出问题
        //p[0] = 'a';
        //cout << "after assign, it is " <<p[0] <<endl;
        delete [] p;

        char *p1 = new char[10];
        cout << "the address pointed by p1 is "<<(void *)p1 <<endl;
        cout << "p1[10] is " << p1[10] <<endl;
        //多于4991就不行了。
        cout << "p1[4991] is "<<p1[4991] <<endl;
        delete [] p1;
       
        return;
}

/*=====================结果分析===========================
the address pointed by p is 00371C10
p[0] is
p[1] is
... ...
p[50] is
... ...
p[100] is
p[5103] is

the address pointed by p1 is 00371C80
p1[10] is
p1[4991] is

分析:
00371C10偏移5104个字节的地址是00373000
00371C80偏移4992个字节的地址也是00373000
看来00373000之后是不能访问的空间,可能是别的进程的地址空间
那么可以得出结论:
------------------------------------------------------
通过一个有效的指针可以访问该指针后面进程允许访问的空间
不管后面的空间是否已经分配。
------------------------------------------------------
=========================================================*/

86

主题

2251

帖子

2384

积分

金牌会员

Rank: 6Rank: 6

积分
2384
QQ
发表于 2007-10-27 15:10:00 | 显示全部楼层

Re:对于new char[0]又研究了一下

你的结论跟问题本身没多少关系啊

6

主题

65

帖子

67

积分

注册会员

Rank: 2

积分
67
 楼主| 发表于 2007-10-27 15:14:00 | 显示全部楼层

Re: Re:对于new char[0]又研究了一下

funcman: Re:对于new char[0]又研究了一下

你的结论跟问题本身没多少关系啊

是的,我仍然不知道new[0]到底有什么用。希望高手能指教。

86

主题

2251

帖子

2384

积分

金牌会员

Rank: 6Rank: 6

积分
2384
QQ
发表于 2007-10-27 16:11:00 | 显示全部楼层

Re:对于new char[0]又研究了一下

《Effective C++》条款8

6

主题

65

帖子

67

积分

注册会员

Rank: 2

积分
67
 楼主| 发表于 2007-10-27 17:02:00 | 显示全部楼层

Re:对于new char[0]又研究了一下

条款8: 写operator new和operator delete时要遵循常规
“c++标准要求,即使在请求分配0字节内存时,operator new也要返回一个合法指针。(实际上,这个听起来怪怪的要求确实给c++语言其它地方带来了简便)”

“有趣的是,如果base不是独立的类,sizeof(base)有可能是零”
这个是分配0字节的用途之一吗?

54

主题

2917

帖子

3765

积分

论坛元老

Rank: 8Rank: 8

积分
3765
QQ
发表于 2007-10-27 21:41:00 | 显示全部楼层

Re:对于new char[0]又研究了一下

真有空,研究这个简直在浪费自己时间。
你这么做:
char *p = new char[0]; 访问p[0]

char *p = new char[1]; 访问p[1]
有什么区别?
象new char[0]是属于有弊无利的行为。

6

主题

65

帖子

67

积分

注册会员

Rank: 2

积分
67
 楼主| 发表于 2007-10-27 22:42:00 | 显示全部楼层

Re:对于new char[0]又研究了一下

比没研究前搞清楚了一些问题,呵呵。写个程序试一下还是很快的。

18

主题

82

帖子

86

积分

注册会员

Rank: 2

积分
86
发表于 2007-11-3 14:42:00 | 显示全部楼层

Re:对于new char[0]又研究了一下

C++中虽然不允许定义长度为0的数组,但明确指出 动态分配长度为0的数组 是合法的,他返回的是一个合法的非0指针,这个指针与一般new返回的指针有所不同,他不能进行解引用操作(如果进行解引用操作,那么结果是undefined 的),因为他不指向任何对象,但可以进行比较操作,比如:
int size = getsize() ;
int *p = new [size] ;
for( int *q = p ; q != p + size ; ++q )
     //do something

这里如果getsize() 返回为0 的话,那么for循环就不会进入,因为size = 0 ;而q 是恒等于p 的,所以q != p + size 不成立,因此不会进入for循环
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-19 05:54

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表