Запутался в указателях
18.12.2012, 23:32
|
|
|
Гражданин KAZUS.RUN
Регистрация: 04.08.2006
Сообщений: 911
Сказал спасибо: 28
Сказали Спасибо 180 раз(а) в 139 сообщении(ях)
|
Re: запутался в указателях)
Вам пытаются сказать, что надо объявить
static char datetime[15];
....
Либо объявить массив глобальным.. либо использовать динамическую память ... Хотя последнее, наверное не этот случай.
|
|
|
|
19.12.2012, 10:41
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 26.11.2011
Адрес: Анапа
Сообщений: 1,618
Сказал спасибо: 284
Сказали Спасибо 129 раз(а) в 111 сообщении(ях)
|
Re: Запутался в указателях
Сообщение от SasaVitebsk
|
|
Вам пытаются сказать, что надо объявить
|
я понял, спасибо  объявил
|
|
|
|
19.12.2012, 15:16
|
|
|
Частый гость
Регистрация: 12.10.2010
Сообщений: 27
Сказал спасибо: 0
Сказали Спасибо 19 раз(а) в 14 сообщении(ях)
|
Re: Запутался в указателях
Сообщение от whoim
|
я понял, спасибо объявил
|
Кстати, тут возможны варианты, особенно для систем с маленьким количеством памяти и оптимизаторами разной степени кривости..
Например для
void* Foo()
{
static uint8_t array1[15];
return array1;
}
память для array1 будет выделена в системе раз и навсегда (+ обнулена в C Startup). Если эта функция вызывается 1 раз за все время жизни, то считай, что память потеряна зря.
Для случая типа
{
const size_t KArrSz = 24;
uint8_t scracthArray[KArrSz];
Foo1(scracthArray, KArrSz);
DoSomething(scracthArray, KArrSz);
}
память для scracthArray[] будет выделена на стеке и теоретически будет возвращена системе при выходе масива из области видимости (блок {..})
Ну, а при динамическом распределении памяти надо ее освобождать ручками, если это не C++ и используется RAII
|
|
|
|
Сказали "Спасибо" Красный Свин
|
|
|
19.12.2012, 16:13
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 26.11.2011
Адрес: Анапа
Сообщений: 1,618
Сказал спасибо: 284
Сказали Спасибо 129 раз(а) в 111 сообщении(ях)
|
Re: Запутался в указателях
Это си.. Из динамики есть например:
|
Цитата:
|
void RS485_send_byte(uint8_t chr)
{
while (!(USARTE0.STATUS & USART_DREIF_bm));
USARTE0.DATA = chr;
}
void RS485_send_str(const char *str)
{
while(*str)
RS485_send_byte(*(str++));
}
|
я так понимаю, это просто передача указателя на ячейку и работа по нему с инкрементом пока не встретится \0? То есть если передаем фтуда обычно инициализированный массив char my[10], то никакие дополнительно области памяти не задействуются (идет чтение по указателю на массив) а судьба my[10] определяется уже нами в дальнейшем порядке?
|
|
|
|
19.12.2012, 16:28
|
|
|
Частый гость
Регистрация: 12.10.2010
Сообщений: 27
Сказал спасибо: 0
Сказали Спасибо 19 раз(а) в 14 сообщении(ях)
|
Re: Запутался в указателях
Сообщение от whoim
|
Это си.. Из динамики есть например:
я так понимаю, это просто передача указателя на ячейку и работа по нему с инкрементом пока не встретится \0? То есть если передаем фтуда обычно инициализированный массив char my[10], то никакие дополнительно области памяти не задействуются (идет чтение по указателю на массив) а судьба my[10] определяется уже нами в дальнейшем порядке?
|
Ну да, все правильно. Самое главное, чтобы массив данных (в теории-строка), передаваемый в качестве параметра, всегда оканчивался '\0'. Иначе - undefined behavior. Написание безопасных программ на голом С - то еще искусство...
например:
const char[] myString = "0123456789";
char buf[15];
memcpy(buf, myString, 2);
RS485_send_str(buf); // жопа!!
|
|
|
|
19.12.2012, 16:44
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 26.11.2011
Адрес: Анапа
Сообщений: 1,618
Сказал спасибо: 284
Сказали Спасибо 129 раз(а) в 111 сообщении(ях)
|
Re: Запутался в указателях
Ну, "0" в начале строки у нас в данном случае - символ ведь?
Кстати, есть еще такая работа с указателем, уже и не помню откуда родилась..
|
Цитата:
|
char *num_to_string(uint32_t _v, uint8_t _w)
{
static char _buff_i[7];
switch (_w) {
case 0: sprintf(_buff_i, "%u", _v); break;//number
case 1: sprintf(_buff_i, "%01u", _v); break; //0x
case 2: sprintf(_buff_i, "%02u", _v); break; //00x
case 3: sprintf(_buff_i, "%03u", _v); break; //000x
case 4: sprintf(_buff_i, "%04u", _v); break; //0000x
case 5: sprintf(_buff_i, "%05u", _v); break; //00000x
case 6: sprintf(_buff_i, "%06lu", _v); break; //000000x
case 11: sprintf(_buff_i, "%c", _v); //char
}
return _buff_i;
}
|
значение передается в процедурку, которая в цикле бегает опять же пока не обнаружит 0. Параметром передается число. Вот мне интересно - static char buff один и тот же или каждый раз новую память отъедает? А то иногда платка перегружается.. думаю - питание (от дешевого программатора через USB + 1117-3.3) или такие вот реализации виноваты?
по поводу \0 - тут подсказывали, что sprintf автоматом его вставляет, правда? Отвел под него [7] место, у меня максимум 6 байт задействовано под данные
|
|
|
|
19.12.2012, 17:11
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 08.06.2008
Сообщений: 1,393
Сказал спасибо: 4
Сказали Спасибо 183 раз(а) в 167 сообщении(ях)
|
Re: Запутался в указателях
Уж лучше так пользовать sprintf.
const char *format[]=
{
"%01u", //0x
"%02u", //00x
"%03u", //000x
"%04u", //0000x
"%05u", //00000x
"%06lu",//000000x
"%c" //char
};
sprintf(buf,format[w], _v);
|
|
|
|
Сказали "Спасибо" Boba_spb
|
|
|
19.12.2012, 17:12
|
|
|
Частый гость
Регистрация: 12.10.2010
Сообщений: 27
Сказал спасибо: 0
Сказали Спасибо 19 раз(а) в 14 сообщении(ях)
|
Re: Запутался в указателях
Сообщение от whoim
|
Ну, "0" в начале строки у нас в данном случае - символ ведь?
Кстати, есть еще такая работа с указателем, уже и не помню откуда родилась..
значение передается в процедурку, которая в цикле бегает опять же пока не обнаружит 0. Параметром передается число. Вот мне интересно - static char buff один и тот же или каждый раз новую память отъедает? А то иногда платка перегружается.. думаю - питание (от дешевого программатора через USB + 1117-3.3) или такие вот реализации виноваты?
по поводу \0 - тут подсказывали, что sprintf автоматом его вставляет, правда? Отвел под него [7] место, у меня максимум 6 байт задействовано под данные
|
Какой ужос! Оно, конечно, даже будет работать, иногда....
Потенциальные проблемы:
1. при передаче в функцию _w == 10, на выходе получаем мусор. Результат - undefined behavior (UB)
2. При передаче в функцию числа _v == 11111111 получим переполнение буфера _buff_i[7]. Результат: UB
3. Возврат char* (если есть возможность вернуть const char*) - вызывающая сторона может модифицировать значение _buff_i[7] снаружи функции.
4. глупое использование повторяющихся многочисленных шаблонов форматирования типа "%0u" итд. Каждый шаблон жрет ROM, это строка.
5. статический буфер внутри функции. ХЗ, может это и приемлемо с архитектурной точки зрения.
|
|
|
|
Сказали "Спасибо" Красный Свин
|
|
|
19.12.2012, 17:28
|
|
|
Почётный гражданин KAZUS.RUN
Регистрация: 26.11.2011
Адрес: Анапа
Сообщений: 1,618
Сказал спасибо: 284
Сказали Спасибо 129 раз(а) в 111 сообщении(ях)
|
Re: Запутался в указателях
1/2 отслеживаю ручками (просто нет таких данных, превышающих значения максимальные), там данных немного в принципе, каждый формат используется в 1-2 местах максимум..
3 - ну раз работает - значит может работать, модифицирование если и будет то недекларированное мною ))) Хотя обработка идет по прерыванию (uart), и если не успеет закончится.. Надо флаг ввести, занято - не трожь..
4 - а это и правда плохо, но даже намного более удачное решение
Boba_spb не решает конкретно эту проблему.. ничего лучше не придумал. Задача - переводить в строки числа от uint8 до uint32. Кстати пробовал нагугленный синтаксис подстановки в формат своего числа, не захотело работать сцуко, пытался долго. Может, подскажете как?
5 - ну вот на это и грешу, попробую его счас вывести, затещу - не пройдут ли перезагрузки. Раз в минут 40 ребутится МК (в терминале отслеживаю)
|
|
|
|
19.12.2012, 22:01
|
|
|
Гражданин KAZUS.RUN
Регистрация: 04.08.2006
Сообщений: 911
Сказал спасибо: 28
Сказали Спасибо 180 раз(а) в 139 сообщении(ях)
|
Re: Запутался в указателях
Сообщение от Красный Свин
|
|
Написание безопасных программ на голом С - то еще искусство...
|
Да не надо пугать человека. 
И вообще... Как кому на сердце ляжет...
Я начинал всякие там F4, F77, PL/I, Basic, Pascal, много ASM самого разного и потом C. "С" мне больше всего нравится. Понятный, прозрачный, позволяет воплотить всё. Просто супер.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 17:49.
|
|