怎么避免两个指向同一个地址的多次释放问题

wintree 2014-03-05 08:42:52
比如以下代码
#include<stdlib.h>
#include<stdio.h>

int main()
{
int *ptr = malloc(10*sizeof(int));
int *ptr2 = ptr;

if(ptr)
{
free(ptr);
ptr =NULL;
printf("delete one");
}

if(ptr2)
{
free(ptr2);
ptr2=NULL;



printf("delete two");
}
return 0;


}


以上代码肯定有问题。。。这种怎么避免?
...全文
1149 53 打赏 收藏 转发到动态 举报
写回复
用AI写文章
53 条回复
切换为时间正序
请发表友善的回复…
发表回复
wintree 2014-03-22
  • 打赏
  • 举报
回复
引用 49 楼 zeng_c_j 的回复:
这相当于共享资源问题了,可以加上一个引用计数,释放之前先查看引用计数是否清零,清零代表已释放,未清零表示还未释放。
恩恩,说白了就是shard_ptr问题 谢谢
wintree 2014-03-22
  • 打赏
  • 举报
回复
引用 51 楼 xihu1364 的回复:
我觉得楼主想提的问题是 线程1 char* p = malloc..... 将p传给线程2 线程2将p free了并且置空 线程1就不知道如何是好了,因为线程2置空的是p的拷贝 置空了 线程1的p还是指着那块内存
是这个意思,你可以看我的另外一个帖子。。。。就是实际的问题
版主大哥 2014-03-21
  • 打赏
  • 举报
回复
我觉得楼主想提的问题是 线程1 char* p = malloc..... 将p传给线程2 线程2将p free了并且置空 线程1就不知道如何是好了,因为线程2置空的是p的拷贝 置空了 线程1的p还是指着那块内存
夹心饼干 2014-03-21
  • 打赏
  • 举报
回复
忘了C里面有没有引用一说 要么用智能指针 或者 int *&ptr2 = ptr;
zeng_c_j 2014-03-21
  • 打赏
  • 举报
回复
这相当于共享资源问题了,可以加上一个引用计数,释放之前先查看引用计数是否清零,清零代表已释放,未清零表示还未释放。
千树之影 2014-03-20
  • 打赏
  • 举报
回复
楼主的代码逻辑上就不对啊,malloc和free是要一一配对的,这里malloc了一次却有两个free,肯定错的啊
飞天御剑流 2014-03-18
  • 打赏
  • 举报
回复
楼主的纠结是自找的,C++各本论著一直都在阐述类似问题的解决与避免方法,只是很多人都没有理解大师的良苦用心,相反还自以为是垃圾、缺陷,这是自找的。 这类问题有不少代替方法,通常来说,你可以用标准库的容器,把内存管理交给标准库,要么,也可以选择RAII,使用各类smart pointer,楼主的问题可以使用share_pointer。
zhuobattle 2014-03-18
  • 打赏
  • 举报
回复
如果想自己实现,那么可以让内存由对象管理,对象负责内存引用计数的增加和减小。

template <class T>
class CRefCs : public T
{

public:
	CRefCs()
		:m_cRef(0)
	{

	}
	virtual ~CRefCs()
	{

	}
public:

    inline static ULONG ourmax( const ULONG & a, const ULONG & b )
	{
		return a > b ? a : b;
	}
	ULONG AddRef()
	{
		LONG lRef = InterlockedIncrement( &m_cRef );
		_ASSERTE(lRef > 0);

		return ourmax(ULONG(m_cRef), 1ul);
	}

	ULONG Release()
	{
		LONG lRef = InterlockedDecrement( &m_cRef );
		//_ASSERTE(lRef >= 0);
		if (lRef == 0)
		{
			m_cRef++;

			delete this;
			return ULONG(0);
		} else 
		{
			return ourmax(ULONG(m_cRef), 1ul);
		}
	}
	

#if (_MSC_VER > 1310)
	volatile LONG	m_cRef;
#else
	LONG	m_cRef;
#endif
};
wintree 2014-03-18
  • 打赏
  • 举报
回复
引用 35 楼 derekrose 的回复:
[quote=引用 34 楼 wallwind 的回复:] [quote=引用 33 楼 derekrose 的回复:] 这问题一般学生时代 每天能问出来五六个类似的 后来发现我真是浪费时间
透过问题看本质。。。 你是高人,如果简单就无视吧,不要在这里炫耀,你是版主怎么样呢?你是大牛怎么样呢?莫装逼,装逼遭雷劈。 。。我是在多个系统异步状态机会遇到的问题。。。然后简单的随手写的一个东西来讨论。。。。 最后问你一个问题,你这版主怎么当上的。。。这csdn算是完蛋了。 [/quote] 看本质就是在c++里面一般选择用对象管理资源,要不自己构建对象管理handle,要不使用别人写好的类库,或者使用智能指针。c语言中就办法少了一点,你说出你的需求,然后我给你解决方案。我推荐大部分的学生都不要针对某些奇思淫巧进行拓展,这真的是对时间的浪费,学生时间非常宝贵。 我只是阐述一个事实,这种事情本来就是无意义的,我的初衷就是你写了什么代码之后产生了某些联系,然后想到的这个问题,我也可以告诉你去使用智能指针来代替,但是这种类似的提问,在这里几乎天天可见,所以我认为我可以去引导一些学生,让他们可以知道什么东西是重要的,什么是不重要的,我只是这个目的。 对于您对csdn的版主审核制度,你可以去系统管理员处举报或者提出更好的建议。 另外我有没有炫耀,另外你可以去考量一下佛印和苏东坡的故事。[/quote] 你也可以去看一个故事:上山的人问下山的人山顶风景如何,但是上山的人依然还是上去的故事。。。
lming_08 2014-03-18
  • 打赏
  • 举报
回复
很明显楼主的代码是纯C代码。那些C++里的解决方案统统不行
majia2011 2014-03-18
  • 打赏
  • 举报
回复
你的情况,学名叫“double free”,可以google下学习 用内存池,锁也要自己加好
赵4老师 2014-03-18
  • 打赏
  • 举报
回复
怎么避免两个指向同一个地址的多次释放问题 怎么避免两个人同时蹲一个茅坑蹲完冲水时的多次冲水问题 怎么避免两个不同用途的指针指向同一个地址导致释放这两个指针所指对象时发生多次释放问题 怎么避免两个不同屁股的人同时蹲一个茅坑导致蹲完冲水时发生多次冲水问题
zhuyf87 2014-03-18
  • 打赏
  • 举报
回复
c++ 的话,使用智能指针是个好选择。c 的话,貌似只能人为避免了。
derekrose 2014-03-18
  • 打赏
  • 举报
回复
引用 41 楼 supermegaboy 的回复:
楼主的纠结是自找的,C++各本论著一直都在阐述类似问题的解决与避免方法,只是很多人都没有理解大师的良苦用心,相反还自以为是垃圾、缺陷,这是自找的。 这类问题有不少代替方法,通常来说,你可以用标准库的容器,把内存管理交给标准库,要么,也可以选择RAII,使用各类smart pointer,楼主的问题可以使用share_pointer。
NONO 楼主问的是c 我刚开始也看错了 我也以为是c++
derekrose 2014-03-18
  • 打赏
  • 举报
回复
引用 39 楼 wallwind 的回复:
[quote=引用 35 楼 derekrose 的回复:] [quote=引用 34 楼 wallwind 的回复:] [quote=引用 33 楼 derekrose 的回复:] 这问题一般学生时代 每天能问出来五六个类似的 后来发现我真是浪费时间
透过问题看本质。。。 你是高人,如果简单就无视吧,不要在这里炫耀,你是版主怎么样呢?你是大牛怎么样呢?莫装逼,装逼遭雷劈。 。。我是在多个系统异步状态机会遇到的问题。。。然后简单的随手写的一个东西来讨论。。。。 最后问你一个问题,你这版主怎么当上的。。。这csdn算是完蛋了。 [/quote] 看本质就是在c++里面一般选择用对象管理资源,要不自己构建对象管理handle,要不使用别人写好的类库,或者使用智能指针。c语言中就办法少了一点,你说出你的需求,然后我给你解决方案。我推荐大部分的学生都不要针对某些奇思淫巧进行拓展,这真的是对时间的浪费,学生时间非常宝贵。 我只是阐述一个事实,这种事情本来就是无意义的,我的初衷就是你写了什么代码之后产生了某些联系,然后想到的这个问题,我也可以告诉你去使用智能指针来代替,但是这种类似的提问,在这里几乎天天可见,所以我认为我可以去引导一些学生,让他们可以知道什么东西是重要的,什么是不重要的,我只是这个目的。 对于您对csdn的版主审核制度,你可以去系统管理员处举报或者提出更好的建议。 另外我有没有炫耀,另外你可以去考量一下佛印和苏东坡的故事。[/quote] 你也可以去看一个故事:上山的人问下山的人山顶风景如何,但是上山的人依然还是上去的故事。。。[/quote] 这不叫故事 只是臆想 或者说叫寓言,本质上是虚无的,逻辑和构思建立在思维的维度上,俗话说就是在xxx。我只说一点,你缺乏信仰,崇拜情绪,你认为论坛上的话只要不加以标注,就都是对你有敌意的,而我对于你的敌意认为是emotion,这就是思维维度。 而我让你看的是一件 historical fact .并没有要求你去如何解释,你只需要看一下即可,你可以讲给自己听,你需要去讲给自己听,因为比c++能力比什么编程能力更重要的是find you!而不是继续lost。而你给我看的是一个a fabricated story, i like read when i was young
nadleeh 2014-03-17
  • 打赏
  • 举报
回复
引用 30 楼 wallwind 的回复:
[quote=引用 14 楼 nadleeh123 的回复:] [quote=引用 楼主 wallwind 的回复:] 比如以下代码
#include<stdlib.h>
#include<stdio.h>

int main()
{
  int *ptr = malloc(10*sizeof(int));
  int *ptr2 = ptr;

  if(ptr)
  {
     free(ptr);
    ptr =NULL;
    printf("delete one");
  }

  if(ptr2)
  {
    free(ptr2);
    ptr2=NULL;



    printf("delete two");
  }
  return 0;


}
以上代码肯定有问题。。。这种怎么避免?
谁用谁释放,非要自己弄个1对多的平级关系,错了怪谁[/quote] yin
引用 2 楼 lpcads 的回复:
看不出这代码的用途。。。 所以,正常情况下不会写这样的代码,就自然而然避免了。
引用 21 楼 bug1190 的回复:
[quote=引用 14 楼 nadleeh123 的回复:] [quote=引用 楼主 wallwind 的回复:] 比如以下代码
#include<stdlib.h>
#include<stdio.h>

int main()
{
  int *ptr = malloc(10*sizeof(int));
  int *ptr2 = ptr;

  if(ptr)
  {
     free(ptr);
    ptr =NULL;
    printf("delete one");
  }

  if(ptr2)
  {
    free(ptr2);
    ptr2=NULL;



    printf("delete two");
  }
  return 0;


}
以上代码肯定有问题。。。这种怎么避免?
谁用谁释放,非要自己弄个1对多的平级关系,错了怪谁[/quote] 这个回复我喜欢,比其它楼的回复都要好,其它人说的再多再精彩本质上都是一砣翔[/quote] 你们遇到过异步回调函数,携带指针过去的代码?然后需要在携带回来的? 需要多个子系统合作,异步状态机制的代码问题? 那个道理我们都懂。。。。同一个地址内容在不同类的之间使用的时候。。。。。等到你们遇到一些复杂的代码就。。。[/quote] 用个全局的不就ok了? 或者直接先申请一段内存来放指针。
lpcads 2014-03-17
  • 打赏
  • 举报
回复
引用 36 楼 lming_08 的回复:
这个是没办法避免的,只能靠程序员自己控制了! 另外回复楼上的,研究这个问题绝对不是浪费时间,在开发过程中遇到很正常,记得当年找bug时就碰到莫名其妙的挂掉问题,然后花很长时间才发现是内存重复释放
很好避免啊,引用计数 count 为 0 才真的 free 。
lming_08 2014-03-15
  • 打赏
  • 举报
回复
这个是没办法避免的,只能靠程序员自己控制了! 另外回复楼上的,研究这个问题绝对不是浪费时间,在开发过程中遇到很正常,记得当年找bug时就碰到莫名其妙的挂掉问题,然后花很长时间才发现是内存重复释放
derekrose 2014-03-15
  • 打赏
  • 举报
回复
引用 34 楼 wallwind 的回复:
[quote=引用 33 楼 derekrose 的回复:] 这问题一般学生时代 每天能问出来五六个类似的 后来发现我真是浪费时间
透过问题看本质。。。 你是高人,如果简单就无视吧,不要在这里炫耀,你是版主怎么样呢?你是大牛怎么样呢?莫装逼,装逼遭雷劈。 。。我是在多个系统异步状态机会遇到的问题。。。然后简单的随手写的一个东西来讨论。。。。 最后问你一个问题,你这版主怎么当上的。。。这csdn算是完蛋了。 [/quote] 看本质就是在c++里面一般选择用对象管理资源,要不自己构建对象管理handle,要不使用别人写好的类库,或者使用智能指针。c语言中就办法少了一点,你说出你的需求,然后我给你解决方案。我推荐大部分的学生都不要针对某些奇思淫巧进行拓展,这真的是对时间的浪费,学生时间非常宝贵。 我只是阐述一个事实,这种事情本来就是无意义的,我的初衷就是你写了什么代码之后产生了某些联系,然后想到的这个问题,我也可以告诉你去使用智能指针来代替,但是这种类似的提问,在这里几乎天天可见,所以我认为我可以去引导一些学生,让他们可以知道什么东西是重要的,什么是不重要的,我只是这个目的。 对于您对csdn的版主审核制度,你可以去系统管理员处举报或者提出更好的建议。 另外我有没有炫耀,另外你可以去考量一下佛印和苏东坡的故事。
wintree 2014-03-15
  • 打赏
  • 举报
回复
引用 33 楼 derekrose 的回复:
这问题一般学生时代 每天能问出来五六个类似的 后来发现我真是浪费时间
透过问题看本质。。。 你是高人,如果简单就无视吧,不要在这里炫耀,你是版主怎么样呢?你是大牛怎么样呢?莫装逼,装逼遭雷劈。 。。我是在多个系统异步状态机会遇到的问题。。。然后简单的随手写的一个东西来讨论。。。。 最后问你一个问题,你这版主怎么当上的。。。这csdn算是完蛋了。
加载更多回复(33)

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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