为什么分配内存后直接释放会出现访问冲突异常

Why the access violation exception when freeing directly after allocating memory

在释放一些指针时,我遇到了访问冲突。
为了知道发生了什么,我决定在代码的较早阶段要求释放指针,甚至在分配内存之后直接释放指针,但它仍然崩溃。
这意味着我的结构在内存中的处理方式存在严重错误。

我知道在以前版本的代码中,在一些变量的定义之前有一个关键字,但是那个关键字丢失了(它是 #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 的值似乎是 "complete" 地址值。在尝试释放内存时,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:抱歉,我没有意识到你的评论包含了这个问题的实际解决方案。