我用C实现了一个纸牌游戏,下面是我的代码:
甲板h:
#ifndef DECK_H
#define DECK_H
#define S_NUM 4
#define V_NUM 12
#define S_MAXLEN 9
#define V_MAXLEN 6
#define OFLEN 5
typedef char deck_t
[S_NUM * V_NUM]
[S_MAXLEN + V_MAXLEN + OFLEN];
typedef struct {
deck_t *hand;
deck_t *remaining_cards;
} dealed_deck_t;
deck_t *new_deck(void);
void print_deck(const deck_t *);
dealed_deck_t deal(const deck_t *, int);
void free_deck(const deck_t *);
static void deckcpy(const deck_t *const, deck_t *, int);
#endif
甲板c:
#include "deck.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
deck_t *new_deck() {
int i, j, k;
deck_t *cards = calloc(1, sizeof(deck_t));
char suits[S_NUM][S_MAXLEN] = {
"Spades", "Diamonds",
"Hearts", "Clubs"
};
char values[V_NUM][V_MAXLEN] = {
"Ace", "Two", "Three",
"Four", "Five", "Six",
"Seven", "Eight", "Nine",
"Jack", "Queen", "King"
};
for (i = 0; i < S_NUM * V_NUM; ++i) {
memset(*cards[i], 0, strlen(*cards[i]));
}
for (i = 0, j = 0; i < S_NUM; ++i) {
for (k = 0; k < V_NUM; ++k, ++j) {
strcat(*cards[j], values[k]);
strcat(*cards[j], " of ");
strcat(*cards[j], suits[i]);
}
}
return cards;
}
void print_deck(const deck_t *deck) {
for (int i = 0; i < S_NUM * V_NUM && strlen(*deck[i]); ++i) {
printf("%s\n", *deck[i]);
}
}
dealed_deck_t deal(const deck_t *deck, int handsize) {
int i, j;
dealed_deck_t dealed_deck;
dealed_deck.hand = calloc(1, sizeof(deck_t));
dealed_deck.remaining_cards = calloc(1, sizeof(deck_t));
// print_deck(deck);
return dealed_deck;
}
void free_deck(const deck_t *deck) {
free((void *)deck);
}
static void deckcpy(const deck_t *const deck, deck_t *dest, int handsize) {
for (int i = 0; i < handsize; ++i) {
char temp[strlen(*deck[i])];
for (int j = 0; j < strlen(*deck[i]); ++j) {
temp[j] = (*deck[i])[j];
temp[j] = '\0';
}
for (int j = 0; j < strlen(temp); ++j) {
(*dest[i])[j] = temp[j];
(*dest[i])[j] = '\0';
}
}
}
主要c:
#include "deck.h"
int main() {
deck_t *cards = new_deck();
deck_t *hand = deal(cards, 6).hand;
// print_deck(cards);
free_deck(cards);
return 0;
}
问题是deck.c在deal函数中。
当我为
dealed_deck.hand
和dealed_deck.remaining_cards
分配内存时,参数deck
指向的数据会受到影响和更改,因此当我注释这两行时:dealed_deck.hand = calloc(1, sizeof(deck_t));
和dealed_deck.remaining_cards = calloc(1, sizeof(deck_t));
,当我取消对数据的注释时,数据是相同的。我在这里使用
calloc
是因为当我使用malloc时,dealed_deck.hand
和dealed_deck.remaining_cards
所指的数据与deck
所指的数据相同,但是当我使用calloc
时,它们是空的。我需要一种分配内存的方法,而不是弄乱我以前分配的内存和数据,如何做到这一点?
我正在使用MacOS和gcc编译。
谢谢。
最佳答案
线路memset(*cards[i], 0, strlen(*cards[i]));
错误。首先,cards
是用calloc
分配的,因此它被零字节填充,这些字节充当空字符串。因此,如果*cards[i]
指向cards
中的某个内容,strlen
返回零,并且memset
将零字节设置为零。
不幸的是,*cards[i]
只有在i
为零时才有效。由于cards
是指向deck_t
的指针,cards[0]
是第一个deck_t
,它是char
数组的数组。作为一个数组,它会自动转换为指向其第一个元素的指针,即char
数组。那么*cards[0]
就是char
的数组。作为一个数组,它会自动转换为指向其第一个元素的指针,并传递给strlen
。然而,当i
是一个(或更多)时,cards[i]
将是第二个(或更多)deck_t
。但只分配了一个deck_t
的空间。因此*cards[i]
无效;它试图访问未分配的空间。
由于不需要该行(由于calloc
),请将其删除并将其放入循环中。
在strcat(*cards[j]
中,存在同样的问题-*cards[j]
仅当j
为零时才有效。正确的表达式是(*cards)[j]
。
在(*cards)[j]
中,cards
是指向adeck_t
的指针,因此(*cards)
是adeck_t
,它是char
数组的数组。那么(*cards)[j]
是那个数组的元素j
,所以它是一个char
数组。
同样,在print_deck
中,将*deck[i]
更改为(*deck)[i]
。
(通过将deck[i]
的类型更改为(*deck)[i]
,可以更改代码以使用deck
而不是char (*MyType)[S_MAXLEN + V_MAXLEN + OFLEN]
。但是,您可能希望先进行上述更改,并在更改类型之前理解这些更改。)
关于c - 如何动态分配内存而不影响其他动态分配的数据?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55827583/