传递给free()的指针是否必须指向内存块的开头,还是指向内部?
问题在于标题……我搜索但找不到任何东西。
编辑:
我真的没有必要解释这个问题,但是因为人们认为我说的话毫无意义(我问的是错误的问题),这就是问题所在:
由于人们似乎对所有问题的“根”原因非常感兴趣而不是实际提出的问题(因为这显然有助于事情得到更好的解决,让我们看看它是否确实如此),这就是问题所在:
我正在尝试基于NTDLL.dll创建一个D运行时库,这样我就可以将该库用于Win32子系统以外的子系统。 所以这迫使我只与NTDLL.dll链接。
是的,我知道这些function是“无证件”的,并且随时都可能发生变化(即使我打赌一百美元, wcstombs
在20年后仍会做同样的事情,如果它仍然存在的话)。 是的,我知道人们(尤其是微软)不喜欢开发人员链接到该库,并且我可能会因此而受到批评。 是的,上述两点意味着在Win32子系统之前运行的程序如chkdsk和碎片整理程序甚至不应该首先创建,因为它几乎不可能与kernel32.dll或msvcrt.dll之类的东西链接。仍然有NT本地可执行文件,所以我们开发人员应该假装这些阶段是永远不在我们的范围之内。
但不 ,我怀疑这里的任何人都希望我粘贴几千行代码并帮助我浏览它们并试图弄清楚为什么未修改的内存分配被我正在修改的源代码拒绝。 所以这就是为什么我问起一个不同于“根”原因的问题,即使这被认为是社区的最佳实践。
如果事情仍然没有意义,请随时在下面发表评论! 🙂
编辑2:
经过大约8个小时的调试,我终于找到了问题:
事实certificate,如果给它的指针是NULL
, RtlReAllocateHeap()
不会像RtlAllocateHeap()
那样自动工作。
它必须指向块的开头。 将空指针传递给free()
是安全的,但传递未由malloc()
或其某个亲属分配的任何指针都将导致未定义的行为。 有些系统会给你一个运行时错误 – 就像“释放未指向malloced的指针”那样。
编辑:
我写了一个测试程序来获取错误信息。 在我的机器上,这个程序:
#include int main(int argc, char **argv) { int *x = malloc(12); x++; free(x); return 0; }
与此消息崩溃:
app(31550) malloc: *** error for object 0x100100084: pointer being freed was not allocated
你可以传递给free
的唯一东西是从malloc
(或calloc
, realloc
等)返回给你的指针,或NULL。
我猜你是在问,因为你有一些function,你做了一个malloc,你想弄乱数据块,然后在你完成后摆脱它,你不想被打扰原始指针的副本。 它不起作用。
从您添加到现有答案的评论中,您似乎提出了错误的问题。 如果您需要内存对齐,为什么不问这个问题? 询问根本问题而不是询问您的感知解决方案!
所以如果你不介意我会回答你应该问的问题:
Win32中的_aligned_malloc()
支持对齐的内存分配。 它更不等于POSIX memalign()
如果您需要实现对齐分配,则实现起来相当简单:
void* aligned_malloc( size_t size, size_t alignment ) { void* unaligned = malloc( size + alignment ) ; void* aligned = (void*)(((intptr_t)unaligned + alignment) & ~(alignment - 1)); void** free_rec_ptr = ((void**)aligned - 1) ; *free_rec_ptr = unaligned ; return aligned ; } void aligned_free( void* block ) { void** free_rec_ptr = ((void**)block - 1) ; free( *free_rec_ptr ) ; }
alignment
参数必须是2的幂。
FWIW,我最后一次研究C运行时库如何使用malloc
和free
, malloc
给你的块实际上在相对于它给你的指针的负偏移处有一些额外的单词。 这些就像块有多大,以及其他东西。 free
依靠能够找到那些东西。 不知道这是否有任何影响。