Элемент массива, перезаписанный последним в C и SDL

#c #pointers

#c #указатели

Вопрос:

Я знаю, что что-то подобное задавалось много раз, но ни один из других ответов, которые я нашел, не был полезным.

По сути, я пытаюсь создать кучу блоков (пользовательскую структуру) со смещением. Я создаю новый SDL_Rect с пользовательским местоположением и добавляю его в блок с другими свойствами. Затем добавьте этот блок в массив. Проблема в том, что в конце все блоки разделяют прямоугольник из последнего созданного (другие свойства в порядке).

Может кто-нибудь, пожалуйста, помочь мне с этим? Я понятия не имею, как это может быть проблемой с указателем, потому что я ничего не использую повторно, но, по-видимому, это так.

     SDL_Color blockColors[] = 
    {
        {192,  0,  0,  0},
        {192, 64,  0,  0},
        {192,128,  0,  0},
        {192,192,  0,  0},
        {  0,192,  0,  0},
        {  0,  0,192,  0},
    };
    int blockColorCount = 6;

    Block* blocks = malloc(sizeof(Block) * blockColorCount * 25);
    int blockCount = blockColorCount * 25;

    //blocks creation
    for (int y = 0; y < blockColorCount; y  )
    {
        for (int x = 0; x < 25; x  )
        {
            SDL_Rect blockRectangle;
            blockRectangle.x = 25 x*18;
            blockRectangle.y = 180 y*18;
            blockRectangle.w = 18;
            blockRectangle.h = 18;

            Block tempBlock = {amp;blockRectangle,blockColors[y],1,false};
            blocks[y*25   x] = tempBlock;
            printf("%d %dn",blocks[y*25 x],amp;tempBlock);

        }
    }
 
 typedef struct
{
    SDL_Rect* rect;
    SDL_Color color;
    int health;
    bool dead;
} Block;
 

Комментарии:

1. Вы вводите адрес истекающей автоматической переменной в каждый созданный вами блок. Каждый и каждый SDL_Rect * в каждом и когда-либо Block становится висячим указателем, как только все это безумие сделано. Даже последний больше не действителен. Поскольку каждый из них получает ровно один SDL_rect , смею спросить, почему вы просто не создаете rect конкретный объект, а не указатель на указанный-же?

2. Почему вы объявляете rect элемент как указатель? Почему не простой объект без указателя (как в SDL_Rect rect; )?

3. SDL_Rect blockRectangle; >>> Пожалуйста, попробуйте использовать malloc вместо указателей переменных стека. SDL_Rect * blockRectangle = (SDL_Rect *)malloc( sizeof(SDL_Rect));

4. Я сделал rect в качестве указателя, потому что большинство функций SDL запрашивают это. Будут ли блоки [y * 25 x] = tempBlock; не копировать блок в массив?

5.Да, это назначение скопирует tempBlock структуру. Проблема в том, что это поверхностная копия, которая копирует указатель amp;blockRectangle , а не структуру, на которую он указывает. И поскольку вы знаете об операторе address-of amp; , почему бы просто не использовать его, когда вам нужно перейти rect к функциям, нуждающимся в указателе? Чем меньше у вас указателей, тем проще становится ваш код. И чем проще это становится, тем меньше шансов на проблемы.