ошибка: переопределение typedef в c - PullRequest
2 голосов
/ 16 августа 2011

У нас есть задание в школе, где мы получили файл заголовка, и нам нужно его реализовать.Заголовок определяет:

typedef struct Board* BoardP;

, что, на мой взгляд, означает, что BoardP является указателем на структуру Board.Во всяком случае, моя реализация:

typedef struct Board
{
    int width;
    int height;
    char *board;
} *BoardP;

Но я продолжаю получать:

Board.c:21: error: redefinition of typedef ‘BoardP’
Board.h:4: note: previous declaration of ‘BoardP’ was here

Любые идеи относительно того, почему это происходит?Спасибо!

РЕДАКТИРОВАТЬ: еще один вопрос.Как видите, моя структура содержит массив символов.Когда я пишу конструктор, я должен инициализировать (malloc (sizeof (height * width)) сначала массив, а затем структуру? А как насчет использования free ()? Должен ли я сначала освободить массив, а затем структуру? Спасибо

Ответы [ 3 ]

5 голосов
/ 16 августа 2011

Отбросьте typedef из определения.

struct Board
{
    int width;
    int height;
    char *board;
};

Структура - это структура; это не так, как ты всегда должен typedef это. Если честно, я только typedef structs для непрозрачных указателей .

С style(9):

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

1 голос
/ 16 августа 2011

Это происходит потому, что в вашем предварительно написанном заголовочном файле вы должны написать реализацию, для которой вы уже вводите тип данных struct Board * в «новый» тип данных BoardP. Ваше объяснение, что BoardP является указателем на тип данных struct Board, является правильным.

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

Предлагаемое решение будет работать, если у вас еще нет typedef в заголовочном файле.

Поскольку он уже есть в заголовочном файле, в файл .c должен быть помещен только код, предложенный cnicutar (код без typedef).

0 голосов
/ 16 августа 2011

Относительно вашего второго вопроса ...

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

Убедитесь, что правильно обрабатываете свои ошибки - если второй malloc завершится неудачно,вам нужно будет free первый.На самом деле это место, которое многие программисты C любят использовать goto:

struct Board *makeBoard(...)
{
    struct Board *b = malloc(sizeof *b);
    if(b == NULL) goto end1;

    b->board = malloc(...);
    if(b->board == NULL) goto end2;

    // ...

  end2:
    free(b);
  end1:
    return NULL;
}

Когда вы free данные, вам нужно free подобъектов, прежде чем вы освободите главные объекты, если только выхраните указатели на все подобъекты во временных переменных перед free основным объектом.То есть следующее не будет работать:

free(b);
free(b->board);

Поскольку, согласно второму утверждению, b равно free d и не может быть безопасно разыменовано.Лучше всего делать это в обратном порядке.

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