如何使用memset将内存指针设置为NULL?

时间:2008-12-29 22:18:11

标签: c++ null pointers memset

我有一个结构

typedef struct my_s {

   int x;
   ...
} my_T;

my_t * p_my_t;

我想将p_my_t的地址设置为NULL,到目前为止,这是我尝试这样做的方式:

memset (&p_my_t, 0, sizeof(my_t*))

但这对我来说并不合适。这样做的正确方法是什么?


提出质疑 - 提出一个更复杂的问题

以下是我要做的事情:

  • 两个过程,A和B
  • malloc p_my_t在A中,B有N个线程并且可以访问它
  • 开始在A中删除,但我不能简单地释放它,因为B中的线程可能仍在使用它。
  • 所以我调用一个函数,将p_my_t的地址传递给B,在B中将其地址设置为NULL,这样B中的其他线程就不能再使用了
  • 从B回电后,我在A
  • 中释放记忆

注意:在进程之间没有通过共享内存管理内存分配的标准方法。你将不得不仔细考虑发生了什么。

9 个答案:

答案 0 :(得分:20)

不要使用memset初始化空指针,因为这会将内存设置为所有位零,这不能保证是空指针的表示,只需这样做:

p_my_t = NULL;

或同等的:

p_my_t = 0;

答案 1 :(得分:4)

你到底想要做什么? p_my_t已经是一个指针,但你还没有为它分配内存。如果要将指针设置为NULL,只需执行

p_my_t = NULL;

尝试取消引用此指针将导致分段错误(或Windows上的访问冲突)。

一旦指针实际指向某个东西(例如通过malloc()或通过为其指定struct my_T的地址),那么您可以正确memset()它:

memset(p_my_t, 0, sizeof(struct my_T));

这将使整个结构归零,将所有字段设置为零。

答案 2 :(得分:2)

用于设置指向 null 的指针的建议代码是指定0(零)。 Bjarne Stroustrup does它:)无论如何它和NULL一样富有表现力并且不依赖于宏定义。

请注意,NULL不是关键字,它不是保留的,虽然重新定义会让人感到困惑,但没有任何东西说你不应该(不仅仅是样式)。一位同事经常开玩笑说在一些标题中将NULL定义为不同于0的东西只是为了看看其他人的代码是如何表现的。

在即将推出的标准中,将会有一个更具表现力的 nullptr 关键字来识别空指针。

答案 3 :(得分:2)

我想也许你想要

extern void set_t_pointer_to_null(my_T *pp);

并致电

set_t_pointer_to_null(&p_my_t);

,其中

void set_t_pointer_to_null(my_T *pp) { *pp = NULL; }

我不确定是否值得定义一个函数来执行此操作,但我认为这回答了您要问的问题。

答案 4 :(得分:0)

谢谢,这是我要做的事情

  • 两个过程,A和B
  • malloc p_my_t在A中,B有N个线程并且可以访问它
  • 开始在A中删除但我不能简单地释放它,因为B中的线程可能仍在使用。
  • 所以我调用一个函数,将p_my_t的地址传递给B,在B中将其地址设置为NULL,这样B中的其他线程就不能再使用了
  • 从B回电后,我在A
  • 中释放记忆

答案 5 :(得分:0)

根据你的回复(在这篇文章的其他地方)陈述:

  

谢谢,这是我要做的事情

     
      
  • 两个过程,A和B
  •   
  • malloc p_my_t在A,B中有N个线程并且可以访问它
  •   
  • 开始在A中删除但我不能简单地释放它,因为B中的线程可能仍在使用。
  •   
  • 所以我调用一个函数,将p_my_t的地址传递给B,在B中将其地址设置为NULL,这样B中的其他线程就不能再使用了
  •   
  • 从B回电后,我在A
  • 中释放记忆   

您需要的是所有线程和进程之间的某种形式的同步。我不确定你是如何在进程之间共享这个对象的,但我怀疑你是在使用共享内存。

通常我会建议使用共享指针类(例如Boost的shared_ptr类),但我不确定在这种情况下它的效果如何。您可能需要考虑调整您的类,以便它跟踪自己的引用,并可以与Boost intrusive_ptr类一起使用。

这样,进程A可以简单地忘记该对象,当进程B完成时,my_T的实例将知道没有更多的引用并且自行清理。

my_T在内部添加或删除引用时,同步将在这里发挥作用(因此,您不会遇到令人讨厌的竞争条件,它认为它应该自行清理,但实际上仍在使用中)。 / p>

另一种更具“kluge”感觉的方法是给每个my_T实例一个“is-valid”标志,以便使用它的所有进程/线程都知道是否继续这样做。

有关Boost各种指针类的更多详细信息,请查看their documentation

答案 6 :(得分:0)

从阅读多线程评论我应该说没有安全的代码序列来完成你的任务。您将不得不退后一步并重新检查您的算法。

答案 7 :(得分:0)

如果我做对了,memset将无法解决您的问题。如果A和B是单独的进程,那么进程A中的p_my_t将与进程B中的p_my_t不同。您无法在不同进程之间传递指针。我觉得你使用某种IPC机制来同步你的两个进程(例如消息队列),只使用p_my_t = NULL而不是memset。

答案 8 :(得分:0)

根据您的更新,在我看来,您真正想要做的是保护对资源的访问,这意味着您应该使用在进程之间共享的读/写锁来保护ptr到该资源,并在使用前测试ptr。

  • 在共享内存中分配结构。
  • 将ptr分配给共享内存中的结构。
  • 使用读/写锁保护对ptr访问结构。
  • 当初始化或使ptr和结构无效时,进程A应该获取对ptr的WRITE锁。
  • 进程B应该获取对ptr的READ锁,并在使用结构之前测试ptr是否有效