Malloc структуры в C (перенесено с C++)

Я хотел бы зарезервировать некоторое пространство памяти в куче и получить к нему доступ с помощью указателя.

Код отлично работает на C++, но я не могу скомпилировать его на C.

#include <string.h>
#include <stdlib.h>

#define IMG_WIDTH 320

struct cluster_s
{
  uint16_t size;
  uint16_t xMin;
  uint16_t xMax;
  uint16_t yMin;
  uint16_t yMax;
};

static struct cluster_s* detectPills(const uint16_t newPixel[])
{

  static struct cluster_s **pixel = NULL;
  static struct cluster_s *cluster = NULL;

  if (!pixel){
    pixel = (cluster_s**) malloc(IMG_WIDTH * sizeof(struct cluster_s*));
    if (pixel == NULL){
      return NULL;
    }
  }
  if (!cluster){
    cluster = (cluster*) malloc((IMG_WIDTH+1) * sizeof(struct cluster_s));
    if (cluster == NULL){
      return NULL;
    }
    for(int i=0; i<IMG_WIDTH;i++){
      memset(&cluster[i], 0, sizeof(cluster[i]));
      pixel[i] = &cluster[i];
    }
  }
(...)
}

что дает мне следующую ошибку компиляции:

ошибка: 'cluster_s' необъявлено (первое использование в этой функции) пиксель = (cluster_s**) malloc(IMG_WIDTH * sizeof(struct *cluster_s));

Если я закомментирую два вызова malloc, я смогу их скомпилировать. Я также попытался удалить приведение перед malloc и получил ошибку компиляции:

В функции _sbrk_r': sbrkr.c:(.text._sbrk_r+0xc): undefined reference to_sbrk' collect2: ошибка: ld вернул 1 статус выхода

Обновлено: Предложенные ответы верны, проблема исходит от компоновщика, который не находит sbrk

(cluster_s*) ==> (struct cluster_s*) но в C вам все равно не нужны приведения. Если вы получаете ошибку компиляции после удаления приведения, то это не компилятор C, возможно, файл .cpp.
Weather Vane 30.07.2019 11:40

Добавление (struct cluster_s*) дает мне ту же ошибку, что и без кастинга. то есть: в функции _sbrk_r': sbrkr.c:(.text._sbrk_r+0xc): неопределенная ссылка to_sbrk' collect2: ошибка: ld вернул 1 статус выхода

Florian K 30.07.2019 11:52

Вы также должны изменить (cluster_s**) в другой строке.

Weather Vane 30.07.2019 11:53

Да, я тоже это сделал.

Florian K 30.07.2019 11:58
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
4
127
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Заменять

struct cluster_s
{
   ...
};

с

typedef struct cluster_s 
{
    ....
}cluster_s;

В C++ структура и класс аналогичны и в большинстве случаев могут использоваться взаимозаменяемо. Таким образом, cluster_s и struct cluster_s могут использоваться оба.

В C cluster_s не определен. Вышеупомянутое изменение определит тип с тем же именем.

Вы можете увидеть ответ Когда следует использовать класс, а когда структуру в C++? для различий между классом и структурой.

Думаю, мне следовало сформулировать свой вопрос по-другому, я всегда получаю одну и ту же странную ошибку после использования любого правильного предложенного ответа для правильного вызова malloc. Ошибка: В функции _sbrk_r': sbrkr.c:(.text._sbrk_r+0xc): undefined reference to _sbrk' collect2: ошибка: ld вернул 1 статус выхода

Florian K 30.07.2019 12:05

Можно пройти через stackoverflow.com/questions/28895703/…. Возможно, это решит проблему _srbk

Rishikesh Raje 30.07.2019 12:20
Ответ принят как подходящий

Этот

I also tried to remove the cast before malloc and got the compilation error:

и это

The code run fine in C++ but I cannot compile it in C.

противоречат друг другу.

Первый означает, что вы пытаетесь скомпилировать программу как программу на C++.

Чтобы заставить программу компилироваться как программу C++ и как программу C, есть два подхода.

Первый — везде в программе использовать спецификатор типа struct cluster_s вместо просто cluster_s. Например

pixel = (struct cluster_s**) malloc(IMG_WIDTH * sizeof(struct cluster_s*));
         ^^^^^^^^^^^^^^^^  
//...
cluster = (struct cluster*) malloc((IMG_WIDTH+1) * sizeof(struct cluster_s));
           ^^^^^^^^^^^^^^

Второй — ввести псевдоним для спецификатора типа struct cluster_s, например

typedef struct cluster_s cluster_s;

Обе возможности дают мне ошибку компиляции: в функции _sbrk_r': sbrkr.c:(.text._sbrk_r+0xc): undefined reference to _sbrk' collect2: ошибка: ld вернул 1 статус выхода

Florian K 30.07.2019 11:59

@FlorianK для чего нужен апостроф? Где функция _sbrk_r'?

Weather Vane 30.07.2019 12:01

@FlorianK Это не имеет ничего общего с заданным вами вопросом. Неопределенная ошибка означает, что компилятор не видит определение _sbrk (или sbrk )

Vlad from Moscow 30.07.2019 12:01

@WeatherVane @Vlad из Москвы Полная ошибка: Компиляция camera.c Ссылка build/ch.elf /home/flo/bin/gcc-arm-none-eabi-7-2018-q2-update/bin/../lib /‌​gcc/arm-none-eabi/7.‌​3.1/../../../../arm-‌​none-eabi/lib/thumb/‌​v7e-m/fpv4-sp /hard/l‌​ibg.a(lib_a-sbrkr.o)‌​: В функции _sbrk_r': sbrkr.c:(.text._sbrk_r+0xc): undefined reference to _sbrk' collect2: error: ld вернул 1 статус выхода lib/ChibiOS/os/common/startup/ARMCMx/compilers/GCC/mk/ rules.‌​mk:204: рецепт для цели 'build/ch.elf' не удалось сделать: *** [build/ch.elf] Ошибка 1

Florian K 30.07.2019 12:10

Разве error: ld не из компоновщик? Это означает, что ошибок компиляции не было.

Weather Vane 30.07.2019 12:12

@FlorianK Как я уже сказал, компоновщик не видит определения sbrk.

Vlad from Moscow 30.07.2019 12:12

Да, кажется, это проблема компоновщика. Без вызова malloc я могу нормально скомпилировать @WeatherVane

Florian K 30.07.2019 12:21

Поэтому, если вы переносите с C++, вам нужны правильные библиотеки.

Weather Vane 30.07.2019 12:23

Другие вопросы по теме