uk_denis 0 12 января, 2021 Опубликовано 12 января, 2021 · Жалоба 4 минуты назад, MrBearManul сказал: Я правильно вас понимаю, что если вынести объявление массива arr[10] из функции func() и сделать его глобальным, то sizeof(arr) вернёт уже размер указателя? Если вынести объявление массива arr[10] из функции func() и сделать его глобальным, то sizeof(arr) вернёт уже размер массива arr, т.е. размер одного элемента массива * на количество элементов массива. Если массив arr[10] объявлен в функции func(), то sizeof(arr) вернёт размер указателя на элементов массива arr. Большие по размерам массивы не стоит объявлять внутри функции, так как локальные объекты хранятся на стеке, а размер стека не такой большой. Если надо объявить большой массив, то это будет глобальный объект или через динамическое выделение памяти в куче malloc для языка С. Работа с глобальными объектами требует меньше времени CPU, чем с объектами в куче, но нет такой гибкости как у объектов в куче. Это небольшое отступление от темы, так как рано или поздно Вы попробуете объявить большой массив на стеке. 15 минут назад, MrBearManul сказал: Я правильно вас понимаю, что если вынести объявление массива arr[10] из функции func() и сделать его глобальным, то sizeof(arr) вернёт уже размер указателя? А разве вы не то же самое говорили, цитирую ниже: Так почему же пример уважаемого @Arlleex вернул 10, а не 4? Пример @Arlleex вернул 10, а не 4? Проверил, тут я не прав. Вернул 10 так как sizeof применен к имени массива, хоть этот объект объявлен на стеке. Тут есть маленький нюанс, что надо передавать именно имя исходного массива в функцию sizeof. В случае передачи массива по указателю будет возвращен размер указателя. Есть примеры использования sizeof: https://www.geeksforgeeks.org/sizeof-operator-c/ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 188 12 января, 2021 Опубликовано 12 января, 2021 · Жалоба 13 минут назад, uk_denis сказал: Если массив arr[10] объявлен в функции func(), то sizeof(arr) вернёт размер указателя на элементов массива arr. Еще раз перечитайте мое сообщение с примером кода. 15 минут назад, uk_denis сказал: так как рано или поздно Вы попробуете объявить большой массив на стеке... Рано или поздно тот, кто сидит между стулом и монитором, начнет включать голову 15 минут назад, uk_denis сказал: Работа с глобальными объектами требует меньше времени CPU, чем с объектами в куче... Это еще с чего бы? На какой архитектуре? 17 минут назад, uk_denis сказал: ...передавать именно имя исходного массива в функцию sizeof... sizeof() - это операция, а не функция. Это в порядке "докапаться" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
uk_denis 0 12 января, 2021 Опубликовано 12 января, 2021 (изменено) · Жалоба del Изменено 12 января, 2021 пользователем uk_denis Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrBearManul 0 12 января, 2021 Опубликовано 12 января, 2021 (изменено) · Жалоба 29 минут назад, uk_denis сказал: Большие по размерам массивы не стоит объявлять внутри функции, так как локальные объекты хранятся на стеке, а размер стека не такой большой Заблуждение. Можно сделать так void foo() { static type_t my_array[MY_ARRAY_SIZE]; } Массив объявлен внутри функции. А размещён будет не на стэке. 29 минут назад, uk_denis сказал: Это небольшое отступление от темы, так как рано или поздно Вы попробуете объявить большой массив на стеке. Простите за прямоту, но чтобы не было недомолвок: ваши познания языка Си пока очень слабы. Этот вывод я делаю не по одному вашему высказыванию, а по нескольким. По-крайней мере в тех областях, которые вы озвучили. Подучите его, тогда и поговорим) 29 минут назад, uk_denis сказал: Работа с глобальными объектами требует меньше времени CPU, чем с объектами в куче, но нет такой гибкости как у объектов в куче. Доказательства? 29 минут назад, uk_denis сказал: или через динамическое выделение памяти в куче malloc для языка С. Которое может оказаться совершенно неприемлимым для встраиваемых систем. 29 минут назад, uk_denis сказал: Если надо объявить большой массив, то это будет глобальный объект Не-а, это не так) Он может быть и локальным, с указанием линковщику разместить его в секции .data или .bss Изменено 12 января, 2021 пользователем MrBearManul Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
uk_denis 0 12 января, 2021 Опубликовано 12 января, 2021 · Жалоба 8 минут назад, Arlleex сказал: 25 минут назад, uk_denis сказал: Работа с глобальными объектами требует меньше времени CPU, чем с объектами в куче... Это еще с чего бы? На какой архитектуре? При выделении объекта из кучи необходим вызов malloc, на который тратится время. При освобождении объекта из кучи надо вызвать free, на что тоже тратиться время. При работе с глобальным объектом во время выполнения программы (runtime) время не тратиться на инициализацию и освобождение памяти, так как объект размещен компилятор по заданному адресе линковщиком. Также возможна проблема фрагментации кучи. При работе с указателями возможен ряд ошибок, поэтому в частности в стандарте MISRA C не используются указатели и выделение памяти из кучи для безопасности, переносимости и надежности программ для встраиваемых систем. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 188 12 января, 2021 Опубликовано 12 января, 2021 · Жалоба 8 минут назад, uk_denis сказал: ...если размер элемента массива не равен единице... необходимо количество элементов массива умножить на размер элемента массива ... memset(my_array, 0xFF, sizeof(my_array[0])*sizeof(my_array)); Что-то опять как-то мимо. С текстом правильно, с кодом - беда. 9 минут назад, uk_denis сказал: ...sizeof возвращает количество элементов массива применительно к имени массива... sizeof() возвращает объем памяти, занимаемый объектом, в эквиваленте элементов char. А char, насколько мне известно, не на всех архитектурах равен 8 битам. В каких-то DSP, вроде, 16 бит. Но это уже лирическое отступление. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
uk_denis 0 12 января, 2021 Опубликовано 12 января, 2021 · Жалоба 10 минут назад, MrBearManul сказал: void foo() { static type_t my_array[MY_ARRAY_SIZE]; } Массив объявлен внутри функции. А размещён будет не на стэке. Массив находится в глобальной области памяти, так как он объявлен через static. Поэтому он размещается не на стеке функции. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 188 12 января, 2021 Опубликовано 12 января, 2021 · Жалоба 3 минуты назад, uk_denis сказал: При выделении объекта из кучи необходим вызов malloc, на который тратится время... А, Вы про это... Я думал, что Вы о работе с уже выделенной памятью. 4 минуты назад, uk_denis сказал: в стандарте MISRA C не используются указатели... А можно прям носом меня ткнуть в место, где это написано? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrBearManul 0 12 января, 2021 Опубликовано 12 января, 2021 · Жалоба 5 минут назад, uk_denis сказал: Массив находится в глобальной области памяти, так как он объявлен через static. Поэтому он размещается не на стеке функции. Насколько я помню, вы утверждали следующее, т.е. дословно: "внутри функции". 44 минуты назад, uk_denis сказал: Большие по размерам массивы не стоит объявлять внутри функции, так как локальные объекты хранятся на стеке, а размер стека не такой большой. 10 минут назад, uk_denis сказал: При выделении объекта из кучи необходим вызов malloc, на который тратится время А во встраиваемых системах нередко не используют штатный "кучер" (ну менеджер кучи). Поэтому он может работать довольно шустро, и время на выделение уже будет довольно малым по сравнению со временем работы с данными. И вообще, почему вы вдруг заговорили о куче? Её вроде никто не упоминал) 13 минут назад, uk_denis сказал: так как объект размещен компилятор по заданному адресе линковщиком Компилятор не занимается размещением по адресам. Это полностью работа линкера, и подчиняется правилам, заданным в скрипте, управляющим им. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
uk_denis 0 12 января, 2021 Опубликовано 12 января, 2021 · Жалоба 3 часа назад, Arlleex сказал: А можно прям носом меня ткнуть в место, где это написано? MISRA-C 2004 Guidelines for the use of the C language in critical systems Rule 20.4 (required): Dynamic heap memory allcocation shall not be used. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 188 12 января, 2021 Опубликовано 12 января, 2021 · Жалоба 4 часа назад, Arlleex сказал: 4 часа назад, uk_denis сказал: в стандарте MISRA C не используются указатели... А можно прям носом меня ткнуть в место, где это написано? 21 минуту назад, uk_denis сказал: Rule 20.4 (required): Dynamic heap memory allcocation shall not be used. Странный диалог. До свидания Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darth Vader 0 12 января, 2021 Опубликовано 12 января, 2021 · Жалоба 4 часа назад, uk_denis сказал: Dynamic heap memory allcocation shall not be used. Не следует использовать динамическое выделение памяти в куче. Вы же утверждали, что 8 часов назад, uk_denis сказал: в стандарте MISRA C не используются указатели Но это всё отступление от темы. А вот это очень показательный ваш код: void func1(); void func2(); #define SIZE_BUF 50 uint8_t my_array[SIZE_BUF]; void main() { func1(my_array); } void func1() { memset(my_array, 0x00, sizeof(my_array[0])*sizeof(my_array)); func2(); } void func2() { memset(my_array, 0xFF, sizeof(my_array[0])*sizeof(my_array)); } Вы бы его через компилятор пропустили для начала, ошибки поисправляли. Ничего странного в func1() не видите? Несоответствие между объявлением и использованием? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Darth Vader 0 12 января, 2021 Опубликовано 12 января, 2021 · Жалоба 10 часов назад, uk_denis сказал: sizeof возвращает количество элементов массива применительно к имени массива Сами придумали? Если нет - приведите ссылку на источник этих знаний. Цитата из стандарта подойдёт. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 188 12 января, 2021 Опубликовано 12 января, 2021 · Жалоба Вот они, коршуны налетели P.S. @Darth Vader, код тот даже скомпилится Но есть нюансы. Пустые скобки функции в Си сообщают, что та принимает неопределенное кол-во аргументов неопределенных типов. В C++, вроде как, пустые скобки говорят, что аргументов функция не принимает. Поэтому в Си лучше писать [type] func(void). Другое дело, что безопасность такого кода напрямую будет зависеть от принятого соглашения вызовов компилятора (кто чистит стек). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ДЕЙЛ 32 13 января, 2021 Опубликовано 13 января, 2021 · Жалоба 23 hours ago, uk_denis said: Если вынести объявление массива arr[10] из функции func() и сделать его глобальным, то sizeof(arr) вернёт уже размер массива arr, т.е. размер одного элемента массива * на количество элементов массива. Если массив arr[10] объявлен в функции func(), то sizeof(arr) вернёт размер указателя на элементов массива arr. Большие по размерам массивы не стоит объявлять внутри функции, так как локальные объекты хранятся на стеке, а размер стека не такой большой. Если надо объявить большой массив, то это будет глобальный объект или через динамическое выделение памяти в куче malloc для языка С. Работа с глобальными объектами требует меньше времени CPU, чем с объектами в куче, но нет такой гибкости как у объектов в куче. Это небольшое отступление от темы, так как рано или поздно Вы попробуете объявить большой массив на стеке. Пример @Arlleex вернул 10, а не 4? Проверил, тут я не прав. Вернул 10 так как sizeof применен к имени массива, хоть этот объект объявлен на стеке. Тут есть маленький нюанс, что надо передавать именно имя исходного массива в функцию sizeof. В случае передачи массива по указателю будет возвращен размер указателя. Есть примеры использования sizeof: https://www.geeksforgeeks.org/sizeof-operator-c/ Вот поэтому более универсальным способом будет заполнение массива тем способом, который я ранее предложил. Если использовать просто sizeof(arr), то при переобъявлении массива из локального в глобальный можно забыть про его заполнение в какой-нибудь функции. Хотя я сам тонкости в цитате не знал, но заполняю массив таким способом из интуитивных соображений как более универсальным и однозначным. memset(buf_2, 0xFF, sizeof(uint8_t) * SIZE_BUF); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться