指向结构的指针不递增
Pointer to a struct is not incrementing
我是 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);
*/
}
您的代码显然会导致未定义的行为。
如果你想用指针来做,请考虑下面的代码。
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;
}
这里比较大的问题是card的申报范围。局部变量在堆栈上分配,当它们超出范围时,内存在某种意义上是 "freed"(可用于其他地方,尽管可能不会重新初始化为零)。您的循环不断使用相同的内存区域,因为 card 超出范围,并在下一次循环迭代时重新创建。
正如其他人所指出的,您需要静态声明一个卡片数组,或者使用 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);
}
}
我是 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);
*/
}
您的代码显然会导致未定义的行为。 如果你想用指针来做,请考虑下面的代码。
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;
}
这里比较大的问题是card的申报范围。局部变量在堆栈上分配,当它们超出范围时,内存在某种意义上是 "freed"(可用于其他地方,尽管可能不会重新初始化为零)。您的循环不断使用相同的内存区域,因为 card 超出范围,并在下一次循环迭代时重新创建。
正如其他人所指出的,您需要静态声明一个卡片数组,或者使用 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);
}
}