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

发布于 2024-07-11 12:40:32 字数 633 浏览 10 评论 0原文

我有一个结构,

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
  • 在A中malloc p_my_t,B有N个线程并且可以访问它
  • 开始在A中删除但我不能简单地释放它,因为 B 中的线程可能仍在使用它。
  • 所以我调用一个函数,将 p_my_t 的地址传递给 B 以将 B 中的地址设置为 NULL,这样 B 中的其他线程就不能再使用
  • 从 B 回调后,然后释放 A 中的内存

NB:没有标准通过进程之间的共享内存来管理内存分配的方法。 您必须相当仔细地思考正在发生的事情。

I have a structure

typedef struct my_s {

   int x;
   ...
} my_T;

my_t * p_my_t;

I want to set the address of p_my_t to NULL and so far this is how I've tried to do this:

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

This doesn't not look right to me though. What is the correct way of doing this?


Amendment to question - asking a radically more complex question:

Here is what I am trying to do:

  • Two processes, A and B
  • malloc p_my_t in A, B has N threads and can access it
  • Start deleting in A but I can not simply free it since threads in B may still using it.
  • So I call a function, pass address of p_my_t to B to set its address to NULL in B so no other threads in B can use anymore
  • After call back from B, I then free memory in A

NB: there is no standard way to manage memory allocations via shared memory between processes. You will have to do some rather careful thinking about what is going on.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

治碍 2024-07-18 12:40:32

不要使用 memset 来初始化空指针,因为这会将内存设置为所有位为零,这不能保证是空指针的表示,只需执行以下操作:

p_my_t = NULL;

或等效操作:

p_my_t = 0;

Don't use memset to initialize a null pointer as this will set the memory to all bits zero which is not guaranteed to be the representation of a null pointer, just do this:

p_my_t = NULL;

or the equivalent:

p_my_t = 0;
丿*梦醉红颜 2024-07-18 12:40:32

你到底想做什么? p_my_t 已经是一个指针,但您尚未为其分配内存。 如果您想将指针设置为 NULL,只需执行

p_my_t = NULL;

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

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

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

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

What exactly are you trying to do? p_my_t is already a pointer, but you haven't allocated memory for it. If you want to set the pointer to NULL, simply do

p_my_t = NULL;

Trying to dereference this pointer will result in a segmentation fault (or access violation on Windows).

Once the pointer actually pointers to something (e.g. via malloc() or by assigning to it the address of a struct my_T), then you can properly memset() it:

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

This will zero out the entire structure, setting all fields to zero.

泪眸﹌ 2024-07-18 12:40:32

将指针设置为 null 的建议代码是分配 0(零)。 Bjarne Stroustrup 做到了 :) 无论如何,它的表现力就像NULL 并且不依赖于宏定义。

请注意,NULL 不是关键字,它不是保留的,虽然重新定义会令人困惑,但没有什么表明您不应该这样做(不仅仅是样式)。 一位同事经常开玩笑说在某些标头中将 NULL 定义为不同于 0 的值,只是为了看看其他人的代码的行为如何。

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

The recommended code for setting a pointer to null is assigning 0 (zero). Bjarne Stroustrup does it :) Anyway it is just as expressive as NULL and does not depend on a macro definition.

Note that NULL is not a keyword, it is not reserved and while it would be confusing to redefine, nothing says that you should not (more than style). A coworker often jokes about defining NULL to something different than 0 in some header just to see how other people's code behave.

In the upcoming standard there will be a more expressive nullptr keyword to identify a null pointer.

禾厶谷欠 2024-07-18 12:40:32

我想也许你想要

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; }

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

I think maybe you want

extern void set_t_pointer_to_null(my_T *pp);

and call

set_t_pointer_to_null(&p_my_t);

where

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

I'm not sure it's worth defining a function to do this, but I think this answers the question you're trying to ask.

内心荒芜 2024-07-18 12:40:32

谢谢,这是我尝试做的

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

Thanks, here is what I an trying to do

  • two processes, A and B
  • malloc p_my_t in A, B has N threads and can access it
  • start deleting in A but I can not simply free it since threads in B may still using.
  • so I call a function, pass address of p_my_t to B to set its address to NULL in B so no others threads in B can use anymore
  • After call back from B, I then free memory in A
二智少女猫性小仙女 2024-07-18 12:40:32

根据您的回复(本文其他地方)指出:

谢谢,这就是我想做的

  • 两个进程,A 和 B
  • A 中的 malloc p_my_t,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 在内部添加或删除引用时,同步将在这里发挥作用(这样您就不会遇到令人讨厌的竞争条件,它认为应该清理自己,但实际上仍在使用)。

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

有关 Boost 各种指针类的更多详细信息,请查看他们的文档< /a>.

Per your reply (elsewhere in this post) stating:

Thanks, here is what I an trying to do

  • two processes, A and B
  • malloc p_my_t in A, B has N threads and can access it
  • start deleting in A but I can not simply free it since threads in B may still using.
  • so I call a function, pass address of p_my_t to B to set its address to NULL in B so no others threads in B can use anymore
  • After call back from B, I then free memory in A

What you need is some form of synchronization between all your threads and processes. I'm not sure of how you are sharing this object between processes, but I suspect you are using shared memory.

Normally I would recommend using a shared pointer class (such as Boost's shared_ptr class), but I'm not sure of how well that would work in this scenario. You may want to consider tweaking your class so that it tracks its own references and can be used with the Boost intrusive_ptr class.

That way, process A can simply forget about the object, and when process B is finished, the instance of my_T will know that there are no more references left and clean itself up.

The synchronization would come into play here when my_T is adding or removing references internally (so you don't run into nasty race conditions where it thinks it should clean itself up but is really still in use).

One other approach that has a bit more of a "kluge" feel to it is to give each instance of my_T an "is-valid" flag so that all processes/threads using it will know whether or not to continue doing so.

For more details on Boost's various pointer classes, check out their documentation.

落花浅忆 2024-07-18 12:40:32

通过阅读您的多线程注释,我应该说没有安全的代码序列来完成您的任务。 您将必须退后一步并重新检查您的算法。

From reading your multi-thread comments I should say there is no safe sequence of code to accomplish your task. You will have to step back and reexamine your algorithm.

紫瑟鸿黎 2024-07-18 12:40:32

如果我做对了, memset 不会解决你的问题。 如果 A 和 B 是独立的进程,则进程 A 中的 p_my_t 与进程 B 中的 p_my_t 不同。您只是不能在不同进程之间传递指针。 我建议你使用某种 IPC 机制来同步你的两个进程(例如消息队列),并且只使用 p_my_t = NULL 而不是 memset。

If I get it right, memset won't solve your problem. If A and B are separate processes, then p_my_t in process A will be different form p_my_t in process B. You just can't pass a pointer between different processes. I sugest you use some kind of IPC mechanism in order to sinchronyze your two processes (message queues, for example), and just using p_my_t = NULL instead of memset.

幽梦紫曦~ 2024-07-18 12:40:32

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

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

Per your update, it seems to me that what you are really trying to do is guard access to a resource, which means you should use a read/write lock that is shared between the processes to guard the ptr to that resource, and test the ptr before using.

  • Allocate the structure in shared memory.
  • Allocate the ptr to the structure in shared memory.
  • Guard access to the ptr to the structure with a Read/Write lock.
  • Process A should acquire a WRITE lock to the ptr when initializing or invalidating the ptr and structure.
  • Process B should acquire a READ lock to the ptr, and test that the ptr is valid before using the structure
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文