Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Красивый и безопасный код в С

Ответить
Настройки темы
Красивый и безопасный код в С

Аватара для hasherfrog

Старый параноик


Сообщения: 2423
Благодарности: 85


Конфигурация

Профиль | Отправить PM | Цитировать


Стандартная ошибка начинающего (и не только) программиста - переполнение буфера при копировании строк. Вот не совсем корректный код:
Код: Выделить весь код
#define SZSIZE 100 
char sz[SZSIZE]; 
strcpy(sz, pszSomeData);
Совсем не вариант, который тем не менее часто используют (100 - как пример):
Код: Выделить весь код
char sz[SZSIZE*100]; 
strcpy(sz, pszSomeData);
Более приемлимый вариант:
Код: Выделить весь код
char sz[SZSIZE]; 
strncpy(sz, pszSomeData, sizeof(sz));
Но тут есть неприятность - последний символ может оказаться не 0. Тогда последующий strlen(sz) может дать сбой. Очевидно, если предусмотреть и эту возможность, надо предохраниться, дописав нулик руками. Но вот какой вариант "красивее"?

Такой:
Код: Выделить весь код
char sz[SZSIZE]; 
strncpy(sz, pszSomeData, sizeof(sz) - 1); 
strcat(sz, "\0");
Или такой:
Код: Выделить весь код
char sz[SZSIZE + 1]; 
strncpy(sz, pszSomeData, SZSIZE); 
sz[SZSIZE] = '\0';
Или такой:
Код: Выделить весь код
char sz[SZSIZE]; 
strncpy(sz, pszSomeData, sizeof(sz)); 
sz[SZSIZE - 1] = '\0';
Может, ещё кто какой вариант знает?

Добавлено:

О, забыл.
Код: Выделить весь код
char sz[SZSIZE]; 
memset(sz, 0, sizeof(sz)); 
strncpy(sz, pszSomeData, sizeof(sz) - 1);
Очевидно, что memset придётся вызывать каждый раз перед копированием.

Отправлено: 13:01, 06-07-2004

 

редкий гость


Сообщения: 1696
Благодарности: 44

Профиль | Сайт | Отправить PM | Цитировать


Извращаться - так красиво.
Код: Выделить весь код
int len;
char *sz;

len = strlen(data) + 1;
sz = (char*)alloca(len);

strcpy(sz, data);
/* или */
memcpy(sz, data, len);
P.S. Ненавижу венгерскую нотацию.

-------
http://ivank.ru


Отправлено: 17:55, 06-07-2004 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Старожил


Сообщения: 185
Благодарности: 1

Профиль | Отправить PM | Цитировать


перефразируем
Код: Выделить весь код
#define strNcpy(dest,src,maxsize) \
   { \
      strncpy(dest, src, maxsize - 1); \
      dest[maxsize-1]=0; \
   }
P.S. на с++ все красивее будет, однако

-------
I like to move it, move it.


Отправлено: 07:19, 07-07-2004 | #3


Аватара для hasherfrog

Старый параноик


Сообщения: 2423
Благодарности: 85

Профиль | Отправить PM | Цитировать


ivank
Фишка в том, что использование динамической памяти накладывает на программиста обязательство следить за использованными ресурсами. Убирать за собой мусор - тоже своего рода искусство. Но если предположить, что всё будет почищено , то ещё вариант:
Код: Выделить весь код
char *psz; 
psz = strdup(pszSomeData); 
//... 
if (psz) free(psz); psz = NULL;

Отправлено: 14:37, 07-07-2004 | #4


редкий гость


Сообщения: 1696
Благодарности: 44

Профиль | Сайт | Отправить PM | Цитировать


hasherfrog
Так alloca - не динамисечкая память, в этом вся фишка Она на стеке память выделяет. Правда, может возникнуть stack overflow.

-------
http://ivank.ru


Отправлено: 20:35, 07-07-2004 | #5


Аватара для hasherfrog

Старый параноик


Сообщения: 2423
Благодарности: 85

Профиль | Отправить PM | Цитировать


ivank
Да, я лоханулся, alloca а не alloc. Не заметил во-первых, а во-вторых, я никогда ей не пользуюсь из-за man alloca:
Цитата:
Эта функция не регламентируется стандартами POSIX или SUSv3.
А для меня POSIX - критично.

Отправлено: 09:51, 08-07-2004 | #6


редкий гость


Сообщения: 1696
Благодарности: 44

Профиль | Сайт | Отправить PM | Цитировать


Ну... Я на самом деле тоже, поскольку пользую C++, а там и  (относительно) умные указатели сделать несложно.

Я, кстати, не знаю ни одной юниксообразной операционка , где этой ф-ии не было бы. В Windows оно тоже есть, только alloca_ зовётся. Так что, имхо, из-за непереносимости её не пользовать довольно таки странно.

P.S. В C99 есть массивы перменного размера. Точнее, не совсем переменного. Поскольку, по сути это та же alloca, но присутствующая в стандарте.

-------
http://ivank.ru


Отправлено: 18:49, 08-07-2004 | #7


Аватара для hasherfrog

Старый параноик


Сообщения: 2423
Благодарности: 85

Профиль | Отправить PM | Цитировать


Цитата ivank:
из-за непереносимости её не пользовать довольно таки странно.
И всё-таки траблы будут. Не у всех, конечно. У м$ про _alloc сказано: Security Note: In Windows XP, if _alloca is called inside a try/catch block, you must call _resetstkoflw in the catch block.
Но в общем случае, в принципе, в С можно юзать. Жаль, что strdupa в RTL у м$ нет. Это был бы идеальный вариант.


Отправлено: 09:38, 09-07-2004 | #8


Аватара для hasherfrog

Старый параноик


Сообщения: 2423
Благодарности: 85

Профиль | Отправить PM | Цитировать


Ну вот, сам же и словил багу.
Код: Выделить весь код
char sz[SZSIZE]; 
strncpy(sz, pszSomeData, sizeof(sz) - 1); 
strcat(sz, '\0');
Компилятор ни слова не сказал про одинарные кавычки в последней строке. Поскольку я привык уже к его "многомудрости", искать ошибку пришлось минут двадцать...

Отправлено: 12:12, 13-07-2004 | #9



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Красивый и безопасный код в С

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
EventID - Код: 6006 , код: 6009, код: 6005. Источник - Eventlog. Panathinaikos Устранение критических ошибок Windows 6 15-04-2010 16:22
[решено] Красивый интерфейс GUI Nik_rus AutoIt 16 08-08-2009 21:08
Красивый счет постов Prisoner Флейм 46 25-01-2009 18:14
3RVX - Красивый альтернативный регулятор громкости SAOPP Автоматическая установка приложений 6 11-01-2009 18:52
Как нарисовать красивый шрифт? Den032 Программирование и базы данных 4 29-08-2006 19:52




 
Переход