传递给 free() 的指针必须指向内存块的开头,还是可以指向内部?
问题就在标题中......我搜索了但找不到任何东西。
编辑:
我真的认为没有必要解释这一点,但是因为人们认为我所说的没有意义(而且我问了错误的问题),所以问题是:
因为人们似乎对所有问题的“根本”原因而不是所提出的实际问题非常感兴趣(因为这显然有助于更好地解决问题,让我们看看它是否确实如此),问题是:
我试图使基于 NTDLL.dll 的 D 运行时库,以便我可以将该库用于 Win32 子系统以外的子系统。所以这迫使我只能链接 NTDLL.dll。
是的,我知道这些函数是“未记录的”,并且可能随时更改(尽管我打赌 wcstombs
仍然会执行相同的操作准确 20 年后的事情,如果它仍然存在的话)。是的,我知道人们(尤其是微软)不喜欢开发人员链接到该库,而且我可能会因为这里受到批评。是的,以上两点意味着在 Win32 子系统之前运行的 chkdsk 和碎片整理程序等程序根本不应该被创建,因为它实际上不可能与 kernel32 之类的东西链接.dll 或 msvcrt.dll 并且仍然具有 NT 本机可执行文件,因此我们开发人员应该假装这些阶段永远超出我们的能力范围。
但是不,我怀疑这里有人希望我粘贴几千行代码并帮助我查看它们并尝试找出为什么没有失败的内存分配被拒绝我正在修改的源代码。因此,这就是为什么我问了一个与“根本”原因不同的问题,尽管这被认为是社区的最佳实践。
如果仍然不明白,请随时在下面发表评论! :)
编辑 2:
经过大约 8 个小时的调试,我终于发现了问题:
事实证明,RtlReAllocateHeap()
确实不会像 RtlAllocateHeap( )
如果给它的指针是NULL
。
The question is in the title... I searched but couldn't find anything.
Edit:
I don't really see any need to explain this, but because people think that what I'm saying makes no sense (and that I'm asking the wrong questions), here's the problem:
Since people seem to be very interested in the "root" cause of all the problem rather than the actual question asked (since that apparently helps things get solved better, let's see if it does), here's the problem:
I'm trying to make a D runtime library based on NTDLL.dll, so that I can use that library for subsystems other than the Win32 subsystem. So that forces me to only link with NTDLL.dll.
Yes, I'm aware that the functions are "undocumented" and could change at any time (even though I'd bet a hundred dollars that wcstombs
will still do the same exact thing 20 years from now, if it still exists). Yes, I know people (especially Microsoft) don't like developers linking to that library, and that I'll probably get criticized for the right here. And yes, those two points above mean that programs like chkdsk and defragmenters that run before the Win32 subsystem aren't even supposed to be created in the first place, because it's literally impossible to link with anything like kernel32.dll or msvcrt.dll and still have NT-native executables, so we developers should just pretend that those stages are meant to be forever out of our reaches.
But no, I doubt that anyone here would like me to paste a few thousand lines of code and help me look through them and try to figure out why memory allocations that aren't failing are being rejected by the source code I'm modifying. So that's why I asked about a different problem than the "root" cause, even though that's supposedly known to be the best practice by the community.
If things still don't make sense, feel free to post comments below! :)
Edit 2:
After around ~8 hours of debugging, I finally found the problem:
It turns out that RtlReAllocateHeap()
does not automatically work like RtlAllocateHeap()
if the pointer given to it is NULL
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
它必须指向块的开头。将空指针传递给
free()
是安全的,但传递任何未由malloc()
或其亲属之一分配的指针将导致未定义的行为。有些系统会给你一个运行时错误 - 类似“未分配指针的释放”的内容。编辑:
我编写了一个测试程序来获取错误消息。在我的机器上,该程序:
崩溃并显示以下消息:
It has to point to the beginning of the block. It's safe to pass a null pointer to
free()
, but passing any pointer not allocated bymalloc()
or one of its relatives will cause undefined behaviour. Some systems will give you a runtime error - something along the lines of "Deallocation of a pointer not malloced".Edit:
I wrote a test program to get the error message. On my machine, this program:
Crashes with this message:
您可以传递给
free
的唯一东西是从malloc
(或calloc
,calloc
)返回给您的指针>realloc 等),或 NULL。我猜你问这个问题是因为你有一些执行 malloc 的函数,并且你想弄乱数据块,然后在完成后将其删除,并且你不想费心保留原始指针的副本。事实并非如此。
The only thing you can pass to
free
is a pointer returned to you frommalloc
(orcalloc
,realloc
, etc), or NULL.I'm guessing you're asking because you have some function where you do a malloc, and you want to mess with the data block and then get rid of it when you're done, and you don't want to be bothered keeping a copy of the original pointer around. It doesn't work that way.
从您添加到现有答案的评论来看,您似乎提出了错误的问题。如果您需要内存对齐,为什么不问这个问题呢?询问根本问题,而不是询问您认为的解决方案!
因此,如果您不介意,我将回答您应该问的问题:
Aligned memory Allocation issupported in Win32 by
_aligned_malloc()
。它或多或少相当于 POSIXmemalign()
如果您需要对齐分配的实现,实现起来相当简单:
alignment
参数必须是 2 的幂。From the comments you have added to existing answers, it seems you are asking the wrong question. If memory alignment is what you need, why don't you ask that question? Ask about the root problem rather than asking about your perceive solution!
So if you don't mind I'll answer the question you should have asked:
Aligned memory allocation is supported in Win32 by
_aligned_malloc()
. It is more of less equivalent to POSIXmemalign()
If you need an implementation of aligned allocation, it is fairly simple to implement:
The
alignment
argument must be a power of two.FWIW,上次我研究 C 运行时库如何与
malloc
和free
一起工作时,malloc
为您提供的块实际上有一些相对于它给你的指针的负偏移处的额外单词。这些说明了诸如块有多大之类的事情。免费
依赖于能够找到这些东西。不知道这是否有任何启发。FWIW, the last time I looked into how the C run time library worked with
malloc
andfree
, the block thatmalloc
gives you actually has some extra words at negative offsets relative to the pointer it gives you. These say things like how big the block is, and other stuff.free
relied on being able to find those things. Don't know if that sheds any light.