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

标签 c memory-management 64-bit access-violation 32-bit

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

我知道在以前版本的代码中,在一些变量的定义之前有一个关键字,但是那个关键字丢失了(它是 #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/

相关文章:

java - 处理大型 HashMap 的内存高效方式

java - 将 Java Initial 和 Maximum 内存设置为相同值的性能

Linux 64b,libXinerama.so.1 的问题

linux - 为什么你会在 addr 和 addrlen 设置为 0 的情况下调用 accept()?

c - Valgrind:是否有内存泄漏?

c++ - 是否有任何信号处理算法可以逆向工程如何通过人类的发声系统产生声波?

c - 用于分组的圆括号是否被视为运算符?

c++ - 链表 - 使用后指针在末尾插入

ios - 为什么 UIAlertController 会用 self 创建一个保留周期?

c - 如何使这一动态位范围代码 GCC 兼容 64 位编译器?