0

我正在尝试使用短的 malloc,例如

typedef union _SOME_STRUCT_ {

   struct {

     USHORT u:4;
     USHORT v:4;
     USHORT w:4;

   } x;

   USHORT word;

} SOME_STRUCT, *PSOME_STRUCT;

PSOME_STRUCT p = malloc (sizeof (SOME_STRUCT));

if (p) {

    p->x.u = 0;
}

free (p); // **** RANDOMLY CRASHING HERE ****

我调试了几天,一无所知,

注意(已编辑):Linux 和 gcc 版本 3.4.6 20060404


使用 VALGRIND 发现的问题

但是,我想在这里记录它,以便我的开发人员同伴可能会意识到这种情况......

我实际上已经将结构定义为

typedef union _SOME_STRUCT_ {

   struct {

     USHORT u:4;
     USHORT v:4;
     USHORT w:4;

   } x;

   USHORT word;

} ALBUM, *PALBUM;

以及我还定义的代码中的其他地方

#define ALBUM "album"

因此, sizeof (ALBUM) 指的是 #define 值而不是 typedef ,因此是问题所在。

让我吃惊的是,

这在 C 中是否允许?


4

8 回答 8

3

尝试通过valgrind传递您的程序,这是一个完全免费的开源程序,也许它可以帮助您查看问题所在。不要忘记使用调试符号进行编译: gcc -g [etc] 。

希望这有帮助..

于 2009-05-13T01:22:40.577 回答
3

这个版本的代码对我有用。

#include <stdio.h>
#define USHORT unsigned short

typedef union _SOME_STRUCT_ {
    struct {
        USHORT u:4;
        USHORT v:4;
        USHORT w:4;
    } x;
    USHORT word;
} SOME_STRUCT, *PSOME_STRUCT;

int
main(int c, char *argv[])
{
    PSOME_STRUCT p = malloc (sizeof (SOME_STRUCT));

    if (p) {
        p->x.u = 0;
    }

    free (p); // **** Properly exiting after this ****
}

这是来自 Windows XP 上 Cygwin 的 GDB 调试。

(gdb) p/x sizeof(PSOME_STRUCT)
$1 = 0x4
(gdb) p/x sizeof(p)
$2 = 0x4
(gdb) p/x sizeof(*p)
$3 = 0x2
(gdb) n
23              if (p) {
(gdb) p/x *p
$4 = {x = {u = 0xc, v = 0x4, w = 0x3}, word = 0x534c}

忽略 $4 中的值,数据未初始化。程序正常退出。

除了这些行之外,您的代码中还有其他内容吗?

编辑:并且,免费(0);是一个有效的操作。

于 2009-05-13T02:11:34.527 回答
2

可能是对齐问题。如果您执行以下操作,它是否仍然会崩溃:

   struct {
     USHORT u:4;
     USHORT v:4;
     USHORT w:4;
     USHORT  :4;
   } x;
于 2009-05-13T01:15:31.657 回答
2

问题不在于代码,而是在另一个线程之前或在另一个线程中发生的事情。

我会减少程序的各个部分,直到它停止崩溃,然后逐步将其添加回来,直到您找出导致此问题的部分。根据操作系统/平台,您还可以尝试一些内存检查工具,valgrind/_crtdebug 等。

于 2009-05-13T02:22:02.260 回答
1

如果这个问题发生在你可以调试的地方,你可以通过调用 memcheck 来启动你的调试会话。

内存崩溃的原因通常是堆或释放同一个指针两次。

于 2009-05-13T02:28:59.390 回答
1

你在没有检查 malloc 是否成功的情况下无条件地调用 free(),所以如果 malloc 失败并且 p 是一个 NULL 指针,那么你正在调用 free(NULL)。

在 if (p) 块内移动 free。

这可能不是崩溃的原因,如果没有内存限制,也不应该是这样,但它仍然是一个错误。

稍后添加:doh,free(NULL) 是明确允许的,根据http://www.opengroup.org/onlinepubs/009695399/functions/free.html - 抱歉。

于 2009-05-13T03:19:45.577 回答
1

如果你在 malloc 和 free 之间做一些事情,你可能会意外地超出另一个数组并破坏你自己的堆栈

(如果“p”碰巧不在寄存器中,并且您超出了静态分配的数组并命中堆栈上存储“p”的位置,那么您稍后将尝试释放随机垃圾,因此会出现段错误)

于 2009-05-13T03:25:43.240 回答
0

如果你把 free(p) 放在你的 if 中怎么办?也许(不太可能) malloc 失败了......

于 2009-05-13T01:14:07.700 回答