c - 为包含灵活数组成员的结构动态分配内存

标签 c

我正在尝试制作一款生命游戏,这是我的代码的开始。我的项目的其余部分看起来不错,但在我可以正确地将内存分配给我的结构“堆栈”之前我无法运行它。

 typedef enum {
        CLUBS = 1,
        HEARTS,
        SPADES,
        DIAMONDS
    } cardsuit;

typedef enum {
    ACE_OF = 1,
    TWO_OF,
    THREE_OF,
    FOUR_OF,
    FIVE_OF,
    SIX_OF,
    SEVEN_OF,
    EIGHT_OF,
    NINE_OF,
    TEN_OF,
    JACK_OF,
    QUEEN_OF,
    KING_OF
} cardvalue;

typedef struct {
    enum cardsuit *suit;
    enum cardvalue *value;
} card;

typedef struct {
    int *size;
    int *index;
    int *indexOfPlay;
    card deck[];

} stack;

int main() {
    stack player1;
    stack player2;
    stack playStack;
    stack drawStack;
    int num = 1;
    int ds = 1;

    printf("Please enter the number of decks you wish to use:");
    scanf("%d", &num);
    ds = DECK*num;
    printf("\nYou have chosen to have %d decks, ie: %d cards.\n", num, ds);

    player1 = (stack *) malloc(sizeof (stack)*num);
    player2 = (stack *) malloc(sizeof (stack)*num); 
    player1.deck = malloc( sizeof(player1)*num);
    player2.deck = (card *) malloc(sizeof(card)*num);
    playStack = (stack *) malloc(sizeof (stack)*num);
    drawStack = (stack *) malloc(sizeof (stack)*num);
}

当我像这样运行代码时,我的每个 malloc 调用的分配中都会出现不兼容的类型。我的问题是为我的结构堆栈分配内存的正确方法是什么?

最佳答案

到底为什么要将指向枚举的指针存储在 card 中,而不是简单的enum值(value)观?同样,为什么 stack 中有这么多指针?除了使用超出必要的空间(特别是在 64 位系统上)之外,它还使您的生活变得异常复杂。

您正在使用 C99“灵活数组成员”(FAM) 构造;你必须正确地初始化它,而且我担心你也管理不善。此代码修复了类型声明,并允许每个玩家手中拥有的牌数 ( stack ) 与他们正在玩的牌组中的牌数一样多。请注意如何简单地将 FAM 所需的空间添加到基础结构的大小中。请注意,除了动态分配的空间之外,您不能明智地使用具有 FAM 的结构。当它们不是动态分配时,数组的大小始终为 0,并且无法更改数组的大小。您也不能将它们嵌入到其他结构或数组中(但您可以在其他结构或数组中拥有指向它们的指针)。

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

typedef enum
{
    CLUBS = 1,
    HEARTS,
    SPADES,
    DIAMONDS
} cardsuit;

typedef enum
{
    ACE_OF = 1,
    TWO_OF,
    THREE_OF,
    FOUR_OF,
    FIVE_OF,
    SIX_OF,
    SEVEN_OF,
    EIGHT_OF,
    NINE_OF,
    TEN_OF,
    JACK_OF,
    QUEEN_OF,
    KING_OF
} cardvalue;

typedef struct
{
    cardsuit  suit;
    cardvalue value;
} card;

typedef struct
{
    int size;
    int index;
    int indexOfPlay;
    card deck[];
} stack;

enum { DECK = 52 };

int main(void)
{
    stack *player1;
    stack *player2;
    stack *playStack;
    stack *drawStack;
    int num = 1;
    int ds = 1;

    printf("Please enter the number of decks you wish to use:");
    scanf("%d", &num);
    ds = DECK * num;
    printf("\nYou have chosen to have %d decks, ie: %d cards.\n", num, ds);

    player1   = (stack *) malloc(sizeof(stack) + sizeof(card) * ds);
    player2   = (stack *) malloc(sizeof(stack) + sizeof(card) * ds);
    playStack = (stack *) malloc(sizeof(stack) + sizeof(card) * ds);
    drawStack = (stack *) malloc(sizeof(stack) + sizeof(card) * ds);

    free(player1);
    free(player2);
    free(playStack);
    free(drawStack);
}

有些人会因为 malloc() 的 Actor 阵容而斥责你。 ,他们可能会因为我让 Actor 在场而责备我。我不同意他们的观点,尽管省略 Actor 阵容并没有什么坏处。我确实假设您使用严格的编译选项进行编译,因此您不会调用 malloc() 。范围内没有函数原型(prototype)(即,您永远不会省略 #include <stdlib.h> )。如果你没有那么自律,那么你的选角就不安全。严格的C99要求原型(prototype)有效。

我经常编译:

gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -c cards.c

free()添加了调用,因此代码在这些编译选项下可以干净地编译。

我没有添加代码来检查scanf()调用成功;你可以解决并且应该解决这个问题。

关于c - 为包含灵活数组成员的结构动态分配内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20317909/

相关文章:

c - 用内存表示查询?

c - 如何从tun接口(interface)接收数据到dpdk绑定(bind)的网卡?

c - 二叉树 - 找到 K 个最小元素

c - 如何停止用替换字符 � 替换字符?

c - 是否可以使一些用于创建库的函数对调用者不可用?

c - 未初始化的局部变量错误

C: 带有输入大小的 strcmp 和 stdin 参数

c - 如何使这个 1996 年的 makefile 起作用?

c - Linux 信号量初始化 : error implicit declaration of function 'semaphore_init'

c - 通过 TCP 连接发送格式化消息