C - Realloc失败,因为"足够的空间"

时间:2017-11-04 17:45:33

标签: c realloc

实际上,iam在realloc上失败了。 Perror会返回一个"没有足够的空间"消息,我无法解释自己。

我在W10上用Mingw32编译。没有优化(使用-wall,wextra)。

它用于简单的蛇游戏。 Iam步骤实现一些功能。其实我想简单长大蛇。 (Snake有一个Head Block,还有一些Body Blocks)。

在Init,我使用malloc分配5个Snake Blocks。 SNAKE_START_BLOCKS是每#define

5

我对Block的定义:

// Structs
typedef struct {
    float x;
    float y;
    float w;
    float h;
} Block;

下面:

GameSnake.SB_Body = malloc(SNAKE_START_BLOCKS * sizeof(Block));

    if(GameSnake.SB_Body == NULL)
    {
        printf("Game Subsystem Fehler 'GameSnake': Kann Speicher fuer Blocks nicht laden!\n");
        return false;
    }

    size_t i;
    for(i = 0; i<SNAKE_START_BLOCKS; i++)
    {
        GameSnake.SB_Body[i].w = SNAKE_PICTURE_SIZE;
        GameSnake.SB_Body[i].h = SNAKE_PICTURE_SIZE;
        GameSnake.SB_Body[i].x = GameSnake.SB_Head.x - (((float)i*(float)SNAKE_PICTURE_SIZE/Level.TL_X_Size)+(float)SNAKE_PICTURE_SIZE/Level.TL_X_Size);
        GameSnake.SB_Body[i].y = GameSnake.SB_Head.y;
    }

    GameSnake.SB_Body_Elements = SNAKE_START_BLOCKS;
某些Codeline以后,如果我的食物受到了打击。我叫我的成长函数

// Lets grow the Snake..
bool CSFMLGrowSnake()
{
    GameSnake.SB_Body = realloc(GameSnake.SB_Body, (GameSnake.SB_Body_Elements+1) * sizeof(Block));

    if(GameSnake.SB_Body == NULL)
    {
        printf("Game Subsystem Fehler 'GameSnake': Kann keinen zusaetzlichen Speicher fuer die Snake anfordern!\n");
        perror("Genauer Fehler: ");
        return false;
    }
    else
    {
        GameSnake.SB_Body[GameSnake.SB_Body_Elements].w = SNAKE_PICTURE_SIZE;
        GameSnake.SB_Body[GameSnake.SB_Body_Elements].h = SNAKE_PICTURE_SIZE;

        // Check Direction and Setup the new Block
        // Todo: Prevent New Block appears in tile Border/in Snake/in Item
        if(GameSnake.S_Actual_Direction == UP)
        {
            GameSnake.SB_Body[GameSnake.SB_Body_Elements].x = GameSnake.SB_Body[GameSnake.SB_Body_Elements-1].x;
            GameSnake.SB_Body[GameSnake.SB_Body_Elements].y = GameSnake.SB_Body[GameSnake.SB_Body_Elements-1].y + (float)SNAKE_PICTURE_SIZE/Level.TL_Y_Size;
        }
        else if(GameSnake.S_Actual_Direction == DOWN)
        {
            GameSnake.SB_Body[GameSnake.SB_Body_Elements].x = GameSnake.SB_Body[GameSnake.SB_Body_Elements-1].x;
            GameSnake.SB_Body[GameSnake.SB_Body_Elements].y = GameSnake.SB_Body[GameSnake.SB_Body_Elements-1].y - (float)SNAKE_PICTURE_SIZE/Level.TL_Y_Size;
        }
        else if(GameSnake.S_Actual_Direction == RIGHT)
        {
            GameSnake.SB_Body[GameSnake.SB_Body_Elements].x = GameSnake.SB_Body[GameSnake.SB_Body_Elements-1].x - (float)SNAKE_PICTURE_SIZE/Level.TL_X_Size;
            GameSnake.SB_Body[GameSnake.SB_Body_Elements].y = GameSnake.SB_Body[GameSnake.SB_Body_Elements-1].y;
        }
        else if(GameSnake.S_Actual_Direction == LEFT)
        {
            GameSnake.SB_Body[GameSnake.SB_Body_Elements].x = GameSnake.SB_Body[GameSnake.SB_Body_Elements-1].x + (float)SNAKE_PICTURE_SIZE/Level.TL_X_Size;
            GameSnake.SB_Body[GameSnake.SB_Body_Elements].y = GameSnake.SB_Body[GameSnake.SB_Body_Elements-1].y;
        }

    }

    GameSnake.SB_Body_Elements++;

    return true;
}

我检查了我的数组索引。但这似乎没问题。 然后我在初始化时检查了Element Adresses:

Pointer Adress[0]: 40900000
Pointer Adress[1]: 40800000
Pointer Adress[2]: 40600000
Pointer Adress[3]: 40400000
Pointer Adress[4]: 40200000

让我感到困惑的是,&#34;减少&#34;地址正常吗?!应该是逆转吗?

有时可行,但如果有效,几秒钟后会导致分段错误。如果我在我的成长函数中打印地址,则最新元素的地址为0。

但是在大​​多数情况下,它直接在realloc上失败了 perror message&#34;没有足够的空间&#34;。

我实际上不确定问题出在哪里。也许你可以帮助我或给我一个提示。我不能相信额外的16个字节会溢出我的记忆:O

我在github上有一个repo,如果你想在这里查看整个文件是: https://github.com/MasterOfPenetrator/SnakeGame/blob/master/CSFMLGameSnake.c

欢迎每一位帮助!

提前致谢!

调试器中的一些详细信息

Disassembly:
At this line it breaks:
0x4045b4    mov    0x41026c,%eax
0x4045b9    add    $0x1,%eax
0x4045bc    shl    $0x4,%eax
0x4045bf    mov    %eax,%edx
0x4045c1    mov    0x4101d0,%eax
0x4045c6    mov    %edx,0x4(%esp)
0x4045ca    mov    %eax,(%esp)
0x4045cd    call   0x40b900 <realloc>

Debugger says:
Failure finding "Stack level "
Failure matching reg_output

This is the content of the adress
0x41026c: 05 00 00 00 59 6f 75 72|65 20 43 6f 6f 6c 21 00    ....Youre Cool!.
0x41027c: 00 00 00 00 00 00 00 00|64 00 00 00 0e 01 00 00    ........d.......

which is setted in my init here
strcpy(GameSnake.S_Name, "Youre Cool!");

The structure is here:
typedef struct {
    Block SB_Head;
    Block *SB_Body;

    sfTexture *SB_Head_Texture;
    sfShader *SB_Head_Shader;
    sfRenderStates SB_Head_State;
    sfTexture *SB_Body_Texture;
    sfShader *SB_Body_Shader;
    sfRenderStates SB_Body_State;

    size_t SB_Body_Elements;
    char S_Name[50];

    int S_Health;
    int S_Rotate;
    int S_Score;

    float S_Speed;
    float S_DefaultSpeed;
    float S_LightDistance;
    bool S_Light_FBM;
    bool S_Light_OnOff;

    Direction S_Actual_Direction;
    Direction S_Prev_Direction;

    bool S_Is_Init;
    bool S_Is_Dead;

    bool S_GODMODE;
    bool S_NOCLIP;

    float S_EndItemTime;

} Snake;

现在我很困惑......

更新

我发现错误,对我感到羞耻:(, 在我的PopBlocks函数中,我做了可怕的失败:

for(i = GameSnake.SB_Body_Elements; i>0; i--)
            /\
            ||
I should append a "-1", now it works fine ;)

我想知道非法访问工作多长时间;-) 每次移动都会调用此函数;)

感谢您的帮助!!

0 个答案:

没有答案