在释放一些指针时,我遇到了访问冲突。
为了知道发生了什么,我决定在代码的较早阶段要求释放指针,甚至在分配内存之后直接释放指针,但它仍然崩溃。
这意味着我的结构在内存中的处理方式存在严重错误。
我知道在以前版本的代码中,在一些变量的定义之前有一个关键字,但是那个关键字丢失了(它是 #define
子句的一部分我不能找回来)。
有谁知道这段代码有什么问题或者提到的关键字应该是什么?
typedef unsigned long longword;
typedef struct part_tag { struct part_tag *next;
__int64 fileptr;
word needcount;
byte loadflag,lock;
byte partdat[8192];
} part;
static longword *partptrs;
<keyword> part *freepart;
<keyword> part *firstpart;
void alloc_parts (void) {
part *ps;
int i;
partptrs = (longword*)malloc (number_of_parts * sizeof(longword)); // number... = 50
ps = (part*)&freepart;
for (i=0; i<number_of_parts; i++) {
ps->next = (struct part_tag*)malloc(sizeof(part));
partptrs[i] = (longword)ps->next;
ps = ps->next;
ps->fileptr = 0; ps->loadflag = 0; ps->lock = 0; ps->needcount = 0; // fill in "ps" structure
};
ps->next = nil;
firstpart = nil;
for (i=0; i<number_of_parts; i++) {
ps = (part*)partptrs[i];
free(ps); <-- here it already crashes at the first occurence (i=0)
};
}
提前致谢
在评论中有人问我为什么在分配指针后直接释放它们。这不是程序最初的编写方式,但为了了解导致访问冲突的原因,我以这种方式重写了。
原来:
alloc_parts();
<do the whole processing>
free_parts();
为了分析访问冲突,我将 alloc_parts() 函数应用到我在那里编写的源代码摘录中。关键是,即使直接在分配内存之后,释放也会出错。这怎么可能?
与此同时,我观察到另一个奇怪的现象:
在分配内存时,ps
的值似乎是“完整”的地址值。在尝试释放内存时,ps
的值仅包含内存地址的最后几位。
Example of complete address : 0x00000216eeed6150
Example of address in freeing loop : 0x00000000eeed6150 // terminating digits are equal,
// so at least something is right :-)
这个问题是由 longword
类型引起的:似乎这个类型太小而无法容纳整个内存地址。我已将其替换为另一种类型 (unsigned long long
),但问题仍然存在。
最佳答案
终于折腾了半天,问题解决了:
该程序原本是一个 32 位应用程序,这意味着原始类型 unsigned long
足以保留内存地址。
但是,该程序现在被编译为 64 位应用程序,因此所提到的类型不再足够大以保留 64 位内存地址,因此已使用另一种类型来解决此问题:
typedef intptr_t longword;
这解决了问题。
@Andrew Henle:抱歉,我没有意识到你的评论包含了这个问题的实际解决方案。
关于c - 为什么分配内存后直接释放会出现访问冲突异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42226996/