Я хотел бы зарезервировать некоторое пространство памяти в куче и получить к нему доступ с помощью указателя.
Код отлично работает на 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
Добавление (struct cluster_s*) дает мне ту же ошибку, что и без кастинга. то есть: в функции _sbrk_r': sbrkr.c:(.text._sbrk_r+0xc): неопределенная ссылка to_sbrk' collect2: ошибка: ld вернул 1 статус выхода
Вы также должны изменить (cluster_s**)
в другой строке.
Да, я тоже это сделал.
Заменять
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 статус выхода
Можно пройти через stackoverflow.com/questions/28895703/…. Возможно, это решит проблему _srbk
Этот
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 статус выхода
@FlorianK для чего нужен апостроф? Где функция _sbrk_r'
?
@FlorianK Это не имеет ничего общего с заданным вами вопросом. Неопределенная ошибка означает, что компилятор не видит определение _sbrk (или sbrk )
@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/libg.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
Разве error: ld
не из компоновщик? Это означает, что ошибок компиляции не было.
@FlorianK Как я уже сказал, компоновщик не видит определения sbrk.
Да, кажется, это проблема компоновщика. Без вызова malloc я могу нормально скомпилировать @WeatherVane
Поэтому, если вы переносите с C++, вам нужны правильные библиотеки.
(cluster_s*)
==>(struct cluster_s*)
но в C вам все равно не нужны приведения. Если вы получаете ошибку компиляции после удаления приведения, то это не компилятор C, возможно, файл .cpp.