Указатель на структуру не увеличивается - PullRequest
0 голосов
/ 15 сентября 2018

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

Мой мыслительный процесс для этого кода был:

  • Сначала создайте указатель на карточку.
  • Во-вторых, создайте карточку в цикле for и назначьте поля этой карточки.
  • Наконец, укажите на эту созданную карточку и увеличьте указатель.

Повторите этот процесс по порядкусоздать 52 карты в памяти по адресам подряд.По сути, я собирался создать колоду карт для каждых 8 байтов в памяти, но строка card_ptr++; внутри цикла не работает, как я думал.Любая идея, что здесь не так?

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

#include <stdio.h>

typedef enum {
  SPADES,
  HEARTS,
  DIAMONDS,
  CLUBS,
  NUM_SUITS
} suit_t;

struct card_tag {
  unsigned value;
  suit_t suit;
};
typedef struct card_tag card_t;

int main(){ 

    card_t *card_ptr;
    printf("Initial card pointer created. %d\n", card_ptr);
    for(int i =SPADES; i < NUM_SUITS; i++){
        for(int j = 1; j < 14; j++){
            card_t card;
            card.value = j;
            card.suit = i;
            printf("Card -> Value = %d Suit = %d, is created.\n", card.value, card.suit);
            card_ptr = &card;
            printf("%d points to the last card.\n", card_ptr);
            card_ptr++;
            printf("Pointer is incremented to %p\n\n", card_ptr);
        }   
    }

    /*card_t *card_ptr;
    printf("%d\n", card_ptr);
    card_ptr++;
    printf("%d\n", card_ptr);
    card_ptr++;
    printf("%d\n", card_ptr);
    */
}

Ответы [ 2 ]

0 голосов
/ 15 сентября 2018

Большим вопросом здесь является объем декларации карты.Локальные переменные размещаются в стеке, и когда они выходят за пределы области видимости, память в некотором смысле «освобождается» (доступна для использования в другом месте, хотя, вероятно, не инициализируется заново в ноль).Ваш цикл постоянно использует одну и ту же область памяти, потому что карта выходит из области видимости и воссоздается при следующей итерации цикла.

Как указали другие, вам необходимо либо статически объявить массив карт, либоиспользуйте malloc, чтобы убедиться, что они остаются в куче.

Используя ваш код в качестве отправной точки, вот пример:

Пример (объявить массив карточек и выполнить итерацию с помощью указателя):

card_t deck[52];

card_t *card_ptr = deck; /* Set pointer to the beginning of the array of cards */

printf("Initial card pointer created. %d\n", card_ptr);
for(int i =SPADES; i < NUM_SUITS; i++){
    for(int j = 1; j < 14; j++){
        card_ptr->value = j;
        card_ptr->suit = i;
        printf("Card -> Value = %d Suit = %d, is created.\n", card_ptr->value, card_ptr->suit);
        printf("%d points to the last card.\n", card_ptr);
        card_ptr++;
        printf("Pointer is incremented to %p\n\n", card_ptr);
    }   
}
0 голосов
/ 15 сентября 2018

Ваш код явно ведет к неопределенному поведению. Если вы хотите сделать это с помощью указателей, рассмотрите приведенный ниже код.

1: Сначала необходимо объявить указатель на указатели.

card_t **card_ptr = malloc(sizeof(card_t*)*NUM_SUITS);

2: Затем выделите память для каждого указателя.

card_ptr[i] = malloc(sizeof(card_t)*14);

3: увеличить указатель, как показано ниже.

card_ptr[i]++;

4: освободить память, используя free после выполненной работы.

Пример кода:

#include <stdio.h>
#include<stdlib.h>

typedef enum {
  SPADES,
  HEARTS,
  DIAMONDS,
  CLUBS,
  NUM_SUITS
} suit_t;

struct card_tag {
  unsigned value;
  suit_t suit;
};
typedef struct card_tag card_t;

int main(){ 

    card_t **card_ptr = malloc(sizeof(card_t*)*NUM_SUITS);
    if (card_ptr == NULL) return 0;

    printf("Initial card pointer created. %d\n", card_ptr);

    for(int i =SPADES; i < NUM_SUITS; i++){

        card_ptr[i] = malloc(sizeof(card_t)*14);
        if (card_ptr[i] == NULL) return 0;

        card_t *tempPtr = card_ptr[i];

        for(int j = 1; j < 14; j++){

            tempPtr->value = j;
            tempPtr->suit = i;

            printf("Card -> Value = %d Suit = %d, is created.\n", tempPtr->value, tempPtr->suit);

            printf("%p points to the last card.\n", tempPtr);
            tempPtr++;
            printf("Pointer is incremented to %p\n\n", tempPtr);
        }   
    }

    /*card_t *card_ptr;
    printf("%d\n", card_ptr);
    card_ptr++;
    printf("%d\n", card_ptr);
    card_ptr++;
    printf("%d\n", card_ptr);
    */

     for(int i =SPADES; i < NUM_SUITS; i++){
        free(card_ptr[i]);
        card_ptr[i] = NULL;
     }
    free(card_ptr);
    card_ptr = NULL;

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...