指向结构的指针不会递增

问题描述 投票:1回答:2

我是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);
    */
}
c arrays pointers struct memory-address
2个回答
3
投票

您的代码显然会导致未定义的行为。如果你想用指针做,请考虑下面的代码。

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;

}

1
投票

这里更大的问题是卡的声明范围。局部变量在堆栈上分配,当它们超出范围时,内存在某种意义上被“释放”(可在其他地方使用,但可能不会重新初始化为零)。你的循环不断使用相同的内存区域,因为卡超出了范围,并在下一个循环迭代中重新创建。

正如其他人所指出的那样,你需要静态地声明一组牌,或者使用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);
    }   
}
© www.soinside.com 2019 - 2024. All rights reserved.