我有一个结构
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*))
但这对我来说并不合适。这样做的正确方法是什么?
提出质疑 - 提出一个更复杂的问题:
以下是我要做的事情:
注意:在进程之间没有通过共享内存管理内存分配的标准方法。你将不得不仔细考虑发生了什么。
答案 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)
谢谢,这是我要做的事情
答案 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。