关于同一指针在循环里多次new的问题

ufolr 2014-09-01 10:10:31
我写了如下一段代码

int a = 1;
myclass *p ; //myclass的构造函数myclass(int)
p = NULL;
while(1)
{
cout<<"zzzzzzzyyyy"<<p;
p = new myclass(1);
cout<<"zzzzzzzzzzz"<<p;

..............
后面有用到指针p并对其所指向区域内容有修改,并不是每次循环都会有修改
}

打印结果为:
zzzzzzzzyyyyy 0x0
zzzzzzzzzzzzz 0x4c14158
zzzzzzzzyyyyy 0x4c14158
zzzzzzzzzzzzz 0x5a5f468
zzzzzzzzyyyyy 0x5a5f468
zzzzzzzzzzzzz 0x5a5f468
zzzzzzzzyyyyy 0x5a5f468
zzzzzzzzzzzzz 0x5a65658
zzzzzzzzyyyyy 0x5a65658
zzzzzzzzzzzzz 0x5a5f468
zzzzzzzzyyyyy 0x5a5f468
zzzzzzzzzzzzz 0x5a5f468
zzzzzzzzyyyyy 0x5a5f468
zzzzzzzzzzzzz 0x4bcc590
zzzzzzzzyyyyy 0x4bcc590
zzzzzzzzzzzzz 0x4bcc590
zzzzzzzzyyyyy 0x4bcc590
zzzzzzzzzzzzz 0x5a597e0
zzzzzzzzyyyyy 0x5a597e0
zzzzzzzzzzzzz 0x4c18168
zzzzzzzzyyyyy 0x4c18168
zzzzzzzzzzzzz 0x4bcc110

我很好奇,为什么指针指向的地址有时会变,有时不会变。还有我想知道,当第二次new了之后,第一次new所开辟的内存块是否变永远无法得到释放?
如果要释放先前所开辟的内存块,应该怎样操作呢?
请各位大仙指点一二、感激不尽。
...全文
1658 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
Johnblx 2014-09-02
  • 打赏
  • 举报
回复
仅仅看当前你所贴的这些代码的话, 确实感觉很是匪夷所思
ufolr 2014-09-02
  • 打赏
  • 举报
回复
引用 10 楼 starytx 的回复:
[quote=引用 9 楼 ufolr 的回复:] [quote=引用 2 楼 starytx 的回复:] 你要你丢失了new之后返回的指针,那么就没有机会对其进行释放了,除非程序结束被操作系统收回。 使用完后进行 delete p就可以了。对指针p指向的内容进行修改,不会改变p的值(指向)
嗯,这个我明白。对p指向的内容进行操作,不会改变p指向的地址。 现在是,我对p进行第二次、第三次new操作,这时它所指向的地址就会改变(有时又不改变),当p指向地址发生了变化之后,我就没法对之前的地址进行释放了[/quote]new出来的地址当然不可控啊,你在new时delete原来的不行吗?[/quote] 因为不确定我调用的库是否对我传入的指针进行了delete。我试过在new之前加 if ( p ) { delete p; } 这样的话在循环时会崩溃。 我猜测原因貌似是我后续调用的库的方法里有对传入的指针进行delete(但是不确定是不是每次循环都被delete了)。 所以我想知道是否有方法让我知道指向某一地址的指针是否被delete了。 还有我很好奇,是不是同一指针被delete两次,第二次delete就一定会崩溃。
mujiok2003 2014-09-02
  • 打赏
  • 举报
回复
引用 9 楼 ufolr 的回复:
[quote=引用 2 楼 starytx 的回复:] 你要你丢失了new之后返回的指针,那么就没有机会对其进行释放了,除非程序结束被操作系统收回。 使用完后进行 delete p就可以了。对指针p指向的内容进行修改,不会改变p的值(指向)
嗯,这个我明白。对p指向的内容进行操作,不会改变p指向的地址。 现在是,我对p进行第二次、第三次new操作,这时它所指向的地址就会改变(有时又不改变),当p指向地址发生了变化之后,我就没法对之前的地址进行释放了[/quote] 在对p重新赋值钱都该释放之前的内存。
std::unique_ptr<myclass > up;  // empty
while(1){
cout<<"zzzzzzzyyyy"<<p.get();
       p.reset( new myclass(1));
       cout<<"zzzzzzzzzzz"<<p.get();

}
ufolr 2014-09-02
  • 打赏
  • 举报
回复
引用 3 楼 zilaishuichina 的回复:
为什么指针指向的地址有时会变,有时不会变。 这说明你p = new myclass(1);在你后面有delete p; 你申请了一块内存, 然后释放掉了, 然后你再申请, 那么有可能还是刚刚那块内存 否则不会出现前后两次 new的是相同的地址的, (当然你如果重载了new操作符,那另说) 还有我想知道,当第二次new了之后,第一次new所开辟的内存块是否变永远无法得到释放? 如果你第一次new的地址,你没有保存下来,你第二次new了之后,第一次new所开辟的内存块就只能等到程序结束系统自动回收了 如果要释放先前所开辟的内存块,应该怎样操作呢? 在第二次new之前释放,或者用别的指针保存下来,然后在你想释放的时候释放
后面两个问题我能理解。现在回到第一个问题,理论上来说,如果我没有delete,那么之前申请过的内存块是不可能被再次分配给我new的指针的。 但是在我打印出来的地址里确实发生了两次new出来的地址相同的情况。由于我后面的代码是使用的别人的库,我也不是特别清楚我传过去的指针是否被其库里的方法delete掉了。所以又有两个疑问。 1,会不会编译器有这样的机制,第二次构造的内容和第一次构造的内容相同时,编译器自动将第二次new申请的地址指向第一次new申请的地址。但我觉得这样的可能性很小。 2,假如确实是该指针在后续操作中被delete掉了,是否有方法能让我自己判断出这个指针是否被delete了?
starytx 2014-09-02
  • 打赏
  • 举报
回复
引用 9 楼 ufolr 的回复:
[quote=引用 2 楼 starytx 的回复:] 你要你丢失了new之后返回的指针,那么就没有机会对其进行释放了,除非程序结束被操作系统收回。 使用完后进行 delete p就可以了。对指针p指向的内容进行修改,不会改变p的值(指向)
嗯,这个我明白。对p指向的内容进行操作,不会改变p指向的地址。 现在是,我对p进行第二次、第三次new操作,这时它所指向的地址就会改变(有时又不改变),当p指向地址发生了变化之后,我就没法对之前的地址进行释放了[/quote]new出来的地址当然不可控啊,你在new时delete原来的不行吗?
ufolr 2014-09-02
  • 打赏
  • 举报
回复
引用 2 楼 starytx 的回复:
你要你丢失了new之后返回的指针,那么就没有机会对其进行释放了,除非程序结束被操作系统收回。 使用完后进行 delete p就可以了。对指针p指向的内容进行修改,不会改变p的值(指向)
嗯,这个我明白。对p指向的内容进行操作,不会改变p指向的地址。 现在是,我对p进行第二次、第三次new操作,这时它所指向的地址就会改变(有时又不改变),当p指向地址发生了变化之后,我就没法对之前的地址进行释放了
ufolr 2014-09-02
  • 打赏
  • 举报
回复
引用 1 楼 truelance 的回复:
后面的代码里有delete p;么
后面的代码没有delete p;
cc___999 2014-09-02
  • 打赏
  • 举报
回复
有时候申请的内存地址一样还真不能确定是怎么回事。 如果没有内存地址用来释放内存,只有当进程退出的时候才能释放。
xian_wwq 2014-09-02
  • 打赏
  • 举报
回复
多次new不怕,new和delete配对就行
  • 打赏
  • 举报
回复
没有对应的delete就不会释放
神奕 2014-09-02
  • 打赏
  • 举报
回复
当第二次new了之后,你已经丢失了第一个new的内存块的地址,找不到了肯定就无法释放了啊。。。 如果要释放先前所开辟的内存块,肯定需要用另外一个指针去保存那个地址啊。。。

myclass *temp = p;   // 第二次new之前
p = new myclass(2);
zilaishuichina 2014-09-02
  • 打赏
  • 举报
回复
为什么指针指向的地址有时会变,有时不会变。 这说明你p = new myclass(1);在你后面有delete p; 你申请了一块内存, 然后释放掉了, 然后你再申请, 那么有可能还是刚刚那块内存 否则不会出现前后两次 new的是相同的地址的, (当然你如果重载了new操作符,那另说) 还有我想知道,当第二次new了之后,第一次new所开辟的内存块是否变永远无法得到释放? 如果你第一次new的地址,你没有保存下来,你第二次new了之后,第一次new所开辟的内存块就只能等到程序结束系统自动回收了 如果要释放先前所开辟的内存块,应该怎样操作呢? 在第二次new之前释放,或者用别的指针保存下来,然后在你想释放的时候释放
starytx 2014-09-02
  • 打赏
  • 举报
回复
你要你丢失了new之后返回的指针,那么就没有机会对其进行释放了,除非程序结束被操作系统收回。 使用完后进行 delete p就可以了。对指针p指向的内容进行修改,不会改变p的值(指向)
熊熊大叔 2014-09-02
  • 打赏
  • 举报
回复
后面的代码里有delete p;么
ufolr 2014-09-02
  • 打赏
  • 举报
回复
引用 20 楼 zilaishuichina 的回复:
[quote=引用 18 楼 ufolr 的回复:] 十分感谢! 我给出的代码的int类型只是举了一个例子,实际上的类型也是第三方库里的一个类,这样重载new 操作符能行?以前没有坐过重载new操作符。
你可以试一下, 年轻人要勇于尝试嘛[/quote] 嗯,好的,非常感谢您的帮助,我去试试、
zilaishuichina 2014-09-02
  • 打赏
  • 举报
回复
引用 18 楼 ufolr 的回复:
十分感谢! 我给出的代码的int类型只是举了一个例子,实际上的类型也是第三方库里的一个类,这样重载new 操作符能行?以前没有坐过重载new操作符。
你可以试一下, 年轻人要勇于尝试嘛
ufolr 2014-09-02
  • 打赏
  • 举报
回复
引用 17 楼 Idle_ 的回复:
cout<<"zzzzzzzyyyy"<<p; <<--p指向上一次new的地址 p = new myclass(1); cout<<"zzzzzzzzzzz"<<p; <<--p被替换成本次new的地址 .............. 循环体执行第二次时第一个cout,不就是输出上一次new的地址吗? 当然和循环体第一次执行中第二个cout的内容一样啦。 和是否delete有什么关系?
如你所说,循环体第二次的第一个cou输出的是上一次new的地址,但是你仔细看输出内容,有好几个输出结果是连续输出了4次相同的地址,也就是说有连续两次new申请到了相同的地址。
ufolr 2014-09-02
  • 打赏
  • 举报
回复
引用 16 楼 zilaishuichina 的回复:
[quote=引用 11 楼 ufolr 的回复:] [quote=引用 3 楼 zilaishuichina 的回复:] 为什么指针指向的地址有时会变,有时不会变。 这说明你p = new myclass(1);在你后面有delete p; 你申请了一块内存, 然后释放掉了, 然后你再申请, 那么有可能还是刚刚那块内存 否则不会出现前后两次 new的是相同的地址的, (当然你如果重载了new操作符,那另说) 还有我想知道,当第二次new了之后,第一次new所开辟的内存块是否变永远无法得到释放? 如果你第一次new的地址,你没有保存下来,你第二次new了之后,第一次new所开辟的内存块就只能等到程序结束系统自动回收了 如果要释放先前所开辟的内存块,应该怎样操作呢? 在第二次new之前释放,或者用别的指针保存下来,然后在你想释放的时候释放
后面两个问题我能理解。现在回到第一个问题,理论上来说,如果我没有delete,那么之前申请过的内存块是不可能被再次分配给我new的指针的。 但是在我打印出来的地址里确实发生了两次new出来的地址相同的情况。由于我后面的代码是使用的别人的库,我也不是特别清楚我传过去的指针是否被其库里的方法delete掉了。所以又有两个疑问。 1,会不会编译器有这样的机制,第二次构造的内容和第一次构造的内容相同时,编译器自动将第二次new申请的地址指向第一次new申请的地址。但我觉得这样的可能性很小。 2,假如确实是该指针在后续操作中被delete掉了,是否有方法能让我自己判断出这个指针是否被delete了?[/quote] 1,不会 2,你可以重载下new和delete操作符,然后在这两个函数里面下个断点,就可以知道是不是第三方库把你的指针给删除了

void *operator new(size_t size)
{
	void *p = malloc(size);
	return p;
}

void operator delete(void *p)
{
	free(p);
}
[/quote] 十分感谢! 我给出的代码的int类型只是举了一个例子,实际上的类型也是第三方库里的一个类,这样重载new 操作符能行?以前没有坐过重载new操作符。
阿呆_ 2014-09-02
  • 打赏
  • 举报
回复
cout<<"zzzzzzzyyyy"<<p; <<--p指向上一次new的地址 p = new myclass(1); cout<<"zzzzzzzzzzz"<<p; <<--p被替换成本次new的地址 .............. 循环体执行第二次时第一个cout,不就是输出上一次new的地址吗? 当然和循环体第一次执行中第二个cout的内容一样啦。 和是否delete有什么关系?
zilaishuichina 2014-09-02
  • 打赏
  • 举报
回复
引用 11 楼 ufolr 的回复:
[quote=引用 3 楼 zilaishuichina 的回复:] 为什么指针指向的地址有时会变,有时不会变。 这说明你p = new myclass(1);在你后面有delete p; 你申请了一块内存, 然后释放掉了, 然后你再申请, 那么有可能还是刚刚那块内存 否则不会出现前后两次 new的是相同的地址的, (当然你如果重载了new操作符,那另说) 还有我想知道,当第二次new了之后,第一次new所开辟的内存块是否变永远无法得到释放? 如果你第一次new的地址,你没有保存下来,你第二次new了之后,第一次new所开辟的内存块就只能等到程序结束系统自动回收了 如果要释放先前所开辟的内存块,应该怎样操作呢? 在第二次new之前释放,或者用别的指针保存下来,然后在你想释放的时候释放
后面两个问题我能理解。现在回到第一个问题,理论上来说,如果我没有delete,那么之前申请过的内存块是不可能被再次分配给我new的指针的。 但是在我打印出来的地址里确实发生了两次new出来的地址相同的情况。由于我后面的代码是使用的别人的库,我也不是特别清楚我传过去的指针是否被其库里的方法delete掉了。所以又有两个疑问。 1,会不会编译器有这样的机制,第二次构造的内容和第一次构造的内容相同时,编译器自动将第二次new申请的地址指向第一次new申请的地址。但我觉得这样的可能性很小。 2,假如确实是该指针在后续操作中被delete掉了,是否有方法能让我自己判断出这个指针是否被delete了?[/quote] 1,不会 2,你可以重载下new和delete操作符,然后在这两个函数里面下个断点,就可以知道是不是第三方库把你的指针给删除了

void *operator new(size_t size)
{
	void *p = malloc(size);
	return p;
}

void operator delete(void *p)
{
	free(p);
}
加载更多回复(1)

64,649

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧