[英]Why is this struct literal getting corrupted when passed by address in VS2013 but not gcc/clang?
我正在为我维护的库组装一个Visual Studio 2013解决方案。 该库主要使用竞技场分配,因此我们有一个分配器接口:
#define HAMMER_ALLOCATOR__H__
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct HAllocator_ {
void* (*alloc)(struct HAllocator_* allocator, size_t size);
void* (*realloc)(struct HAllocator_* allocator, void* ptr, size_t size);
void (*free)(struct HAllocator_* allocator, void* ptr);
} HAllocator;
[... API functions ... ]
#ifdef __cplusplus
}
#endif
#endif
我们还实现了malloc
, realloc
和free
的包装器:
#include <string.h>
#include <stdlib.h>
#include "internal.h"
void* system_alloc(HAllocator *allocator, size_t size) {
void* ptr = malloc(size + sizeof(size_t));
*(size_t*)ptr = size;
return (uint8_t*)ptr + sizeof(size_t);
}
void* system_realloc(HAllocator *allocator, void* ptr, size_t size) {
if (ptr == NULL)
return system_alloc(allocator, size);
ptr = realloc((uint8_t*)ptr - sizeof(size_t), size + sizeof(size_t));
*(size_t*)ptr = size;
return (uint8_t*)ptr + sizeof(size_t);
}
void system_free(HAllocator *allocator, void* ptr) {
if (ptr != NULL)
free((uint8_t*)ptr - sizeof(size_t));
}
HAllocator system_allocator = {
.alloc = &system_alloc,
.realloc = &system_realloc,
.free = &system_free,
};
system_allocator
全局在internal.h
( #include
s allocator.h
)中声明为extern
,并作为符号导出(在.def文件中)。 然而,显然该结构是永远不会被初始化,因为当我的单元测试尝试通过system_allocator
按地址到其提领操作的功能alloc
成员,他们与以“0x000007FEFAD3EB6D(hammer.dll)在锤test.exe的未处理的异常段错误:0000005 :访问冲突读取位置0xFFFFFFFFFFFFFFFF。“
检查调试器中的传入指针表明某些东西绝对不对:
特别是因为当我检查原始struct literal时,一切看起来都很合理:
我试图把断点在声明和定义都system_allocator
和VS2013告诉我,“调试器的目标代码类型的无可执行代码与该行相关联。” 这是否意味着system_allocator
实际上没有被初始化? (如果是这样,那么那些0x000007fefad31 ...地址是什么意思?)
我从来没有遇到过gcc或clang这个问题,这是我第一次使用VS. 我错过了什么?
编辑:每chux的评论,失败的测试实际上是在设置失败。 system_allocator像这样传递:
HBitWriter *w = h_bit_writer_new(&system_allocator);
失败的代码行是HBitWriter *h_bit_writer_new(HAllocator* mm__)
的第一行HBitWriter *h_bit_writer_new(HAllocator* mm__)
:
HBitWriter *writer = h_new(HBitWriter, 1);
其中h_new
是#defined as
#define h_new(type, count) ((type*)(mm__->alloc(mm__, sizeof(type)*(count))))
我敢打赌它与DLL有关。 您可能必须将system_allocater成员放在可执行文件中,而不是在DLL看到它时从包含函数地址的DLL传递结构。
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683212%28v=vs.85%29.aspx
断点的问题很容易解释。 Visual C ++调试器通过在函数中放置断点来工作。 你试图在函数外面放置一个断点。 这不受支持。
在机器代码级别,全局初始化器在main
之前在可执行文件中运行,而在DllMain
在DLL的情况下运行。 您可能已经注释掉了MSVC ++的实际初始化程序,因为代码不是有效的C ++。 是的,我知道问题标记为C,但MSVC ++不支持现代C.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.