Dec_NN 0 19 ноября, 2020 Опубликовано 19 ноября, 2020 · Жалоба STM32. STM32CubeIde. Есть глобальный массив. Передаю указатель на него в функцию. Код прописанный в функции меняет значения элементов массива. Затем из этой функции мне необходимо вызвать еще одну, также с указанием данного массива. Вот тут не получается. Вторая функция уже не модифицирует элементы того самого глобального массива. void func1(uint8_t *buf_1); void func2(uint8_t *buf_2); uint8_t my_array[50]; void main { func1(my_array); } void func1(uint8_t *buf_1) { memset(buf_1, 0x00, sizeof(buf_1)); // Здесь все нормально, все элементы my_array устанавливаются в 0 func2(buf_1); } void func2(uint8_t *buf_2) { memset(buf_2, 0xFF, sizeof(buf_2)); // Здесь только первые 4 элемента my_array устанавливаются в FF, остальные не модифицируются } Также компилятор выдает warning: argument to 'sizeof' in 'memset' call is the same expression as the destination; did you mean to provide an explicit length? [-Wsizeof-pointer-memaccess] Понимаю, что как-то ошибочно ссылаюсь на массив при вызове второй функции, но не понимаю как сделать правильно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 19 ноября, 2020 Опубликовано 19 ноября, 2020 · Жалоба 2 minutes ago, Dec_NN said: Здесь все нормально, все элементы my_array устанавливаются в 0 Нет, не нормально. sizeof(buf_1) возвращает размер указателя, а не массива. А элементы и так инициализированы в 0. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HardEgor 87 19 ноября, 2020 Опубликовано 19 ноября, 2020 · Жалоба 6 минут назад, Dec_NN сказал: Понимаю, что как-то ошибочно ссылаюсь на массив при вызове второй функции, но не понимаю как сделать правильно. void main { func1(my_array, sizeof(my_array)); } void func1(uint8_t *buf_1, uint32_t size) { memset(buf_1, 0x00, size); // Здесь все нормально, все элементы my_array устанавливаются в 0 func2(buf_1, 4); } void func2(uint8_t *buf_2, uint32_t size) { memset(buf_2, 0xFF, size); // Здесь только первые 4 элемента my_array устанавливаются в FF, остальные не модифицируются } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dec_NN 0 19 ноября, 2020 Опубликовано 19 ноября, 2020 · Жалоба 37 minutes ago, Dec_NN said: 35 minutes ago, aaarrr said: Нет, не нормально. sizeof(buf_1) возвращает размер указателя, а не массива. А элементы и так инициализированы в 0. Действительно. Вы правы. 25 minutes ago, HardEgor said: void main { func1(my_array, sizeof(my_array)); } void func1(uint8_t *buf_1, uint32_t size) { memset(buf_1, 0x00, size); // Здесь все нормально, все элементы my_array устанавливаются в 0 func2(buf_1, 4); } void func2(uint8_t *buf_2, uint32_t size) { memset(buf_2, 0xFF, size); // Здесь только первые 4 элемента my_array устанавливаются в FF, остальные не модифицируются } Огромное спасибо. Теперь все понял. Проблема не в передаче указателя, а в работе функции sizeof. func2(buf_1, 4) из вашего примера заменил на func2(buf_1, size); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darth Vader 0 19 ноября, 2020 Опубликовано 19 ноября, 2020 · Жалоба 3 часа назад, Dec_NN сказал: Проблема не в передаче указателя, а в работе функции sizeof. Проблема в том, что вы изначально не поняли, что передавая функции указатель на объект, ей надо передать и количество этих объектов, если хотите работать с массивом этих объектов. Откуда функция узнает количество элементов в массиве, имея только указатель на один из его элементов? Код в теле функции не отличает указатель на объект от указателя на массив объектов. Для него они абсолютно одинаковы. Не просто так стандартные функции memset, memcpy, memcmp имеют параметр - размер объекта в байтах. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ДЕЙЛ 32 29 декабря, 2020 Опубликовано 29 декабря, 2020 · Жалоба Я сделал бы так: void func1(uint8_t *buf_1); void func2(uint8_t *buf_2); #define SIZE_BUF 50 uint8_t my_array[SIZE_BUF]; void main { func1(my_array); } void func1(uint8_t *buf_1) { memset(buf_1, 0x00, sizeof(uint8_t) * SIZE_BUF); func2(buf_1); } void func2(uint8_t *buf_2) { memset(buf_2, 0xFF, sizeof(uint8_t) * SIZE_BUF); } Передача нескольких параметров в функцию - это дурной тон. В данном случае только два, что ещё терпимо. А если их несколько, то лучше передать указатель на структуру. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 188 29 декабря, 2020 Опубликовано 29 декабря, 2020 · Жалоба 19 минут назад, ДЕЙЛ сказал: Передача нескольких параметров в функцию - это дурной тон. А пруфы будут? Цитата В данном случае только два, что ещё терпимо. Передаю 4, уже не терпимо? Цитата А если их несколько, то лучше передать указатель на структуру. Чем лучше? Синтаксически - да. По быстроте ~нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ДЕЙЛ 32 29 декабря, 2020 Опубликовано 29 декабря, 2020 · Жалоба 4 minutes ago, Arlleex said: А пруфы будут? Передаю 4, уже не терпимо? Чем лучше? Синтаксически - да. По быстроте ~нет. Параметр передаётся обычно через регистр процессора, число которых ограничено. Если параметров будет слишком много, то передаваться они будут через обычную память, что замедлит выполнение программы. Ещё и размер памяти программы увеличивается при неоптимальном коде. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 188 29 декабря, 2020 Опубликовано 29 декабря, 2020 · Жалоба 1 минуту назад, ДЕЙЛ сказал: Если параметров будет слишком много, то передаваться они будут через обычную память, что замедлит выполнение программы... А Ваша структура, указатель на которую Вы хотите потом передать аргументом, память не требует? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ДЕЙЛ 32 29 декабря, 2020 Опубликовано 29 декабря, 2020 · Жалоба 4 minutes ago, Arlleex said: А Ваша структура, указатель на которую Вы хотите потом передать аргументом, память не требует? Есть структура из 100 параметров. При вызове функции с передачей сотни параметров все они дополнительно копируются сначала в отдельную область памяти, чтобы затем уже внутри функции можно было их оттуда прочитать. При вызове функции с передачей указателя никакого дополнительного копирования не потребуется. Копирование сотни параметров потребует наличия дополнительных инструкций для процессора, регистров или оперативки для буферизации и времени на копирование. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 188 29 декабря, 2020 Опубликовано 29 декабря, 2020 · Жалоба 3 минуты назад, ДЕЙЛ сказал: При вызове функции с передачей указателя никакого дополнительного копирования не потребуется. Это, конечно, очевидно, но это в корне меняет суть: теперь в вызванной функции я могу изменить эти самые параметры, а значит, локальными они уже не являются. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 29 декабря, 2020 Опубликовано 29 декабря, 2020 · Жалоба 44 minutes ago, ДЕЙЛ said: #define SIZE_BUF 50 Это совсем дурной тон - передавать в функцию указатель на массив, размер которого где-то задефайнен. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ДЕЙЛ 32 29 декабря, 2020 Опубликовано 29 декабря, 2020 · Жалоба Сколько способов, столько и мнений. В каждой ситуации идеальным будет компромиссное решение. Это как написать "Hello world" разными способами. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrBearManul 0 29 декабря, 2020 Опубликовано 29 декабря, 2020 (изменено) · Жалоба 1 час назад, ДЕЙЛ сказал: memset(buf_1, 0x00, sizeof(uint8_t) * SIZE_BUF); А чего не так memset(buf_1, 0x00, sizeof(my_array)); ??? 50 минут назад, ДЕЙЛ сказал: то замедлит выполнение программы. Вы так можете говорить только после изучения листингов компилятора. Чего он там намудрит/наоптимизирует - совершенно неочевидно без полного примера кода. 38 минут назад, ДЕЙЛ сказал: Копирование сотни параметров потребует наличия дополнительных инструкций для процессора, регистров или оперативки для буферизации и времени на копирование. Простите, но вы разарботчиков компиляторов совсем не уважаете? Оптимизаторы нынче весьма лихие, и копирование может не понадобится. Однако, если локальная переменная, а именно таковой является аргумент функции, переданный по значинию, меняется, то без копирования не обойтись. 22 минуты назад, ДЕЙЛ сказал: Это как написать "Hello world" разными способами. Правда реальные программы координально отличаются от "Hello World". В общем, изучайте стандарты языка. Тогда и говорить дальше можно будет) 50 минут назад, ДЕЙЛ сказал: Параметр передаётся обычно через регистр процессора, число которых ограничено. А если компилятор заинлайнит функцию? Изменено 29 декабря, 2020 пользователем MrBearManul Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ДЕЙЛ 32 29 декабря, 2020 Опубликовано 29 декабря, 2020 (изменено) · Жалоба 11 minutes ago, MrBearManul said: А чего не так memset(buf_1, 0x00, sizeof(my_array)); ??? Лучше перебдеть и накодить под самый тупой компилятор. my_array может восприняться как указатель на начало массива. 11 minutes ago, MrBearManul said: Вы так можете говорить только после изучения листингов компилятора. Чего он там намудрит/наоптимизирует - совершенно неочевидно без полного примера кода. Простите, но вы разарботчиков компиляторов совсем не уважаете? Оптимизаторы нынче весьма лихие, и копирование может не понадобится. Однако, если локальная переменная, а именно таковой является аргумент функции без ссылки, меняется, то без копирования не обойтись. Правда реальные программы координально отличаются от "Hello World". если компилятор заинлайнит функцию? Упрощение жизни компилятору кашу не испортит. Компиляторы не боги и тоже делают ошибки, для обхода которых иногда приходится менять код алгоритма. 12 minutes ago, MrBearManul said: В общем, изучайте стандарты языка. Тогда и говорить дальше можно будет) Пока только 6 лет непрерывного кодинга на Си, но обязательно изучу язык! Изменено 29 декабря, 2020 пользователем ДЕЙЛ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться