Си. Передача массива констант в функцию, хранение и вызовы

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Си. Передача массива констант в функцию, хранение и вызо

Сообщение ARV »

Если у вас так определена структура и так, как было показано ранее, добавляете в нее элементы массива - это грубейшее нарушение с точки зрения работы с памятью!
Единственное, в чем я не до конца уверен, так это в том, что С++ не делает самостоятельно выделение памяти под это дело... Где-то на 90% я уверен, что не делает и проблем впереди у вас будет МОРЕ, но на 10% сомневаюсь, ибо С++ я знаю хуже, чем бейсик... а бейсик я не знаю вообще.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
RealHann
Открыл глаза
Сообщения: 55
Зарегистрирован: Ср май 14, 2014 15:46:02
Откуда: Харьков

Re: Си. Передача массива констант в функцию, хранение и вызо

Сообщение RealHann »

надеюсь на С++. если вылезут баги, добавлю malloc
Реклама
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Си. Передача массива констант в функцию, хранение и вызо

Сообщение Аlex »

C++ тоже не будет выделять память. Ему, также, нужны всякие malloc'и.
RealHann
Открыл глаза
Сообщения: 55
Зарегистрирован: Ср май 14, 2014 15:46:02
Откуда: Харьков

Re: Си. Передача массива констант в функцию, хранение и вызо

Сообщение RealHann »

Но сейчас-то работает каким-то боком ) И выделение памяти адекватное. Если глюкнет - сразу напишу сюда
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Си. Передача массива констант в функцию, хранение и вызо

Сообщение ARV »

Аlex писал(а):Ему, также, нужны всякие malloc'и
Ну, тогда кранты проекту. Локальная структура после выхода из функции живет в стеке до тех пор, пока не будет затерта очередным обращением к стеку. Это не грабли, а граблищи!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Реклама
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Си. Передача массива констант в функцию, хранение и вызо

Сообщение Аlex »

Код: Выделить всё

struct module_interface_t
{
   char func_cnt;           // количество функций в интерфейсе
   int* interface[];        // массив неопределенной длины
};

struct module_interface_t   DeviceInfo;


int main(int argc, char** argv) {
    
    
    DeviceInfo.func_cnt=3;
    DeviceInfo.interface[0]=(int*) 1;
    DeviceInfo.interface[1]=(int*) 2;       // Это - крах ! Под 1 и 2-ой элементы не выделена память
    DeviceInfo.interface[2]=(int*) 3;       // Тоже самое.
    
    return 0;
}
Добавлено after 16 minutes 48 seconds:
Re: Си. Передача массива констант в функцию, хранение и вызовы
Так будет правильнее :

Код: Выделить всё

struct module_interface_t{
public:
    module_interface_t(unsigned char size){
        interface= new int*[size];
        func_cnt=size;
    }
    ~module_interface_t(){
        delete interface;
    }
    unsigned char func_cnt;     // количество функций в интерфейсе
    int** interface;            // массив указателей неопределенной длины
};


module_interface_t  DeviceInfo(3);


int main(int argc, char** argv) {
    
    
    DeviceInfo.interface[0]=(int*) 1;
    DeviceInfo.interface[1]=(int*) 2;       
    DeviceInfo.interface[2]=(int*) 3;       
    
    
    
    return 0;
}

Реклама
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Си. Передача массива констант в функцию, хранение и вызо

Сообщение ARV »

Лучше и правильнее разобраться, почему не проходит статическая инициализация на этапе компиляции.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
Siarzhuk
Потрогал лапой паяльник
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

Re: Си. Передача массива констант в функцию, хранение и вызо

Сообщение Siarzhuk »

[uquote="RealHann",url="/forum/viewtopic.php?p=3117927#p3117927"]Но сейчас-то работает каким-то боком ) И выделение памяти адекватное.[/uquote]
Память под глобальную переменную DeviceInfo резервируется компилятором/линкером в . bss сегменте. И резервируется она размером sizeof(struct module_interface). Если понапихать в него указателей больше чем этот размер - то совсем другие переменные, следуюшие непосредственно за этой DeviceInfo будут перезаписаны совсем не теми данными чем вы от них ожидаете. И как только такие переменные появятся - грабли, распарывая ковёр из прошлогодних листьев, стремглав рванутся в точку звонкой встречи с вашим лбом. :-D Впрочем, если компилятор достаточно сообразителен, чтобы прикинув использование этой переменной, посчитать ему достаточно большой sizeof - то грабли какое-то время и поскучают в одиночестве. Но это какая-то фантастика. Впрочем, почитайте map-файл - все эти чудеса и непонятки с "выделением памяти" там разъясняются.

Добавлено after 58 seconds:
[uquote="ARV",url="/forum/viewtopic.php?p=3118039#p3118039"]почему не проходит статическая инициализация на этапе компиляции.[/uquote]
Designated инициализации вроде как под [классическими] плюсами не поддерживаются.

Добавлено after 5 minutes 43 seconds:
[uquote="Аlex",url="/forum/viewtopic.php?p=3117937#p3117937"]Так будет правильнее :

Код: Выделить всё

[...]
        interface= new int*[size];
[...]
[/uquote]
Хм... оператор new по дефолту потянет за кулисами столько всякого разнообразного типа поддержки исключений да и тех же самых выделений из Heap, что как бы лекарство пациенту не оказалось неподъёмным. Особенно на МК с небогатым ресурсом.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Си. Передача массива констант в функцию, хранение и вызо

Сообщение ARV »

Siarzhuk писал(а):Designated инициализации вроде как под [классическими] плюсами не поддерживаются
я-то думал, что gcc он как бы это может... но если не может, то тогда предлагаю использовать указатель на массив.

Код: Выделить всё

typedef int (*my_func)(void);

static my_func array[3] = {func1, func2, func3};

typedef struct {
   int cnt;
   my_func  *functions;
} interface_t;

interface_t my_interface = {3, array};

// execute
*(my_interface.functions[2])();
Добавлено after 2 minutes 43 seconds:
Re: Си. Передача массива констант в функцию, хранение и вызовы
Что-то я написал и засомневался - правильно ли написал? с разыменованием у меня всегда какие-то проблемы...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Си. Передача массива констант в функцию, хранение и вызо

Сообщение Аlex »

Реализация с шаблоном :

Код: Выделить всё

/*******************************************************************************/
typedef int (*p_func)(void);

template <unsigned char size>
struct module_interface_t{
public:
    char     func_cnt;              // количество функций в интерфейсе
    p_func   interface[size];       // массив неопределенной длины
    module_interface_t(): func_cnt(size) {}
};
/*******************************************************************************/


/*******************************************************************************/
int func_1(void){
    
}
int func_2(void){
    
}
int func_3(void){
    
}
/*******************************************************************************/

void Interface(void* p){
    module_interface_t<0>* p_interface = (module_interface_t<0>*)p;
    for(unsigned char i=0; i<p_interface->func_cnt; i++){           // Перебираем все функции
        p_interface->interface[i]();                                // И вызываем их по-очереди
    }
    
}

/*******************************************************************************/
int main(int argc, char** argv) {
    
    
    module_interface_t <3>     DeviceInfo;  // Объявляем структуру с размером массива
    
    DeviceInfo.interface[0]=func_1;         // Заполняем массив функций
    DeviceInfo.interface[1]=func_2;         //
    DeviceInfo.interface[2]=func_3;         //
    
    Interface((void*)&DeviceInfo);          // Кидаем структуру на реализацию
    
    
    
    return 0;
}
/*******************************************************************************/
Проверено на g++. Работает.
RealHann
Открыл глаза
Сообщения: 55
Зарегистрирован: Ср май 14, 2014 15:46:02
Откуда: Харьков

Re: Си. Передача массива констант в функцию, хранение и вызо

Сообщение RealHann »

да. с памятью начались ожидаемые грабли. пробую реализовать последний вариант от Alex
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Си. Передача массива констант в функцию, хранение и вызо

Сообщение ARV »

RealHann писал(а):с памятью начались ожидаемые грабли
вы всегда только личному опыту доверяете, а теоретическому обоснованию нет? это ведь было очевидно еще неделю назад...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
RealHann
Открыл глаза
Сообщения: 55
Зарегистрирован: Ср май 14, 2014 15:46:02
Откуда: Харьков

Re: Си. Передача массива констант в функцию, хранение и вызо

Сообщение RealHann »

было все уже написано. оставалось только включить и увидеть. для меня этот опыт важен

Добавлено after 4 hours 10 minutes 58 seconds:
Re: Си. Передача массива констант в функцию, хранение и вызовы
Работает тема! Всем рекомендую :)

Добавлено after 17 minutes 5 seconds:
Re: Си. Передача массива констант в функцию, хранение и вызовы
Alex, спасибо за помощь!
Ответить

Вернуться в «AVR»