Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > strcpy_s vs strcpy


Автор: GoldFinch 14.7.2009, 18:14
есть задача - заполнить массив char[] строкой, неиспользованные байты забить нулями
пишу код
Код

        struct RequestAuthLogin    : serialization::make_simple<RequestAuthLogin>
        {
            static const unsigned char id=0;

            char login[14];
            char password[16];
            unsigned short chksum;

            RequestAuthLogin(const std::string& login_, const std::string& password_, 
                unsigned short chksum_) 
            {
                memset(this,0,sizeof(*this));
                strcpy_s(login,sizeof(login),login_.c_str());
                strcpy_s(password,sizeof(password),password_.c_str());
                chksum=chksum_;
            }
        };

вроде все красиво выглядит, использовал "безопасную" strcpy_s , только вот незадача, эта *нехорошая* функция забивает остаток буфера символами 0xFE

что характерно, в документации об этом ни слова.

Автор: AlexT84 14.7.2009, 19:56
Это только в дебаге. В релизе остаток буфера остаётся нетронутым.

Автор: Vaulter 14.7.2009, 20:12
в дебаге просто буфера сразу содержат 0xFE наверно... а могут 0xCD smile
не суть.
суть: слюшай дарагой! у тебя std::string есть? зачем char* а?

Добавлено через 2 минуты и 29 секунд
Код

memset( login, 0, sizeof( login ) );
memset( password, 0, sizeof( password ) );


пробовал?
а memset( this убери от греха подальше smile

Автор: GoldFinch 14.7.2009, 21:06
Vaulter, 
1) не char* а char[], и потому что так надо. надо - значит надо.
2) зачем вызывать 2 раза memset если можно вызвать 1 раз?
 
AlexT84, 
верю, только мне теперь не дебажить чтоли?

Автор: Rififi 14.7.2009, 23:21
есть задача - заполнить массив char[] строкой, неиспользованные байты забить нулями

char login[14] = {0};
char password[16] = {0};

+ юзать StrSafe API

Автор: Vaulter 14.7.2009, 23:31
Цитата(GoldFinch @  14.7.2009,  22:06 Найти цитируемый пост)
зачем вызывать 2 раза memset если можно вызвать 1 раз?


Цитата(GoldFinch @  14.7.2009,  22:06 Найти цитируемый пост)
надо - значит надо

 smile 

ну две переменных ж.
зачем две переменных?


Автор: jonie 15.7.2009, 08:01
чет я не понимаю смысла использоваяния безопасных функций без проверки их результата...

Автор: GoldFinch 15.7.2009, 08:22
jonie, чтобы ворнинга небыло

Автор: AlexT84 15.7.2009, 10:41
Цитата(GoldFinch @  14.7.2009,  21:06 Найти цитируемый пост)
AlexT84, 
верю, только мне теперь не дебажить чтоли? 
Ну почему же не дебажить? Зайди в настройки проекта: C/C++ -> Code Generation -> Runtime Libruary и выставь там флаг /MT, или /MD. Будет тебе дебаг проект с релизными библиотеками.

Автор: GoldFinch 15.7.2009, 22:08
Цитата(Rififi @  15.7.2009,  00:21 Найти цитируемый пост)

char login[14] = {0};
char password[16] = {0};

в структуре это не работает, см. пост #1

Автор: Vaulter 16.7.2009, 00:27
кстати, boost::serialization
"держит" ВСЕ STL контейнеры

http://www.boost.org/doc/libs/1_39_0/libs/serialization/doc/tutorial.html#serializablemembers


Автор: GoldFinch 16.7.2009, 19:04
Vaulter, я рад за boost::serialization, но у меня своя сериализация, бустовская мне не подходит.

пожалуй действительно лучше забить на странный strcpy и использовать std::string
Код

  struct RequestAuthLogin
        {
            static const unsigned char id=0;
            std::string login;
            std::string password;
            unsigned short chksum;
            RequestAuthLogin(const std::string& login_, const std::string& password_, 
                unsigned short chksum_) : login(login_), password(password_), chksum(chksum_) 
            {
                login.append(14-1-login.size(),0);
                password.append(16-1-password.size(),0);
            }
            template<class Archive>
            void serialize(Archive & ar)
            {
                ar & login;
                ar & password;
                ar & chksum;
            }
        };



Автор: mes 16.7.2009, 20:37
Цитата(GoldFinch @  16.7.2009,  18:04 Найти цитируемый пост)

пожалуй действительно лучше забить на странный strcpy и использовать std::string


Цитата(GoldFinch @  16.7.2009,  18:04 Найти цитируемый пост)
                login.append(14-1-login.size(),0);
                password.append(16-1-password.size(),0);


а не проще написать свою "strcpy" с нужным поведением ? а то код слишком режет глаз...

Автор: GoldFinch 16.7.2009, 20:51
mes, 
код который я использовал до этого
Код

memset(this,0,sizeof(*this));
memcpy(login,login_.c_str(),login_.size());
memcpy(password,password_.c_str(),password_.size());

тоже вобщем-то резал глаз

писать свою strcpy ради такого случая - у нее будет странная функциональность, и я хз где еще ее можно будет использовать

(какбэ задача - чтобы в буфере архива оказались строки логина и пароля выровненные до 14 и 16 байт соответственно)

Автор: mes 16.7.2009, 23:30
Цитата(GoldFinch @  16.7.2009,  19:51 Найти цитируемый пост)
код который я использовал до этого тоже вобщем-то резал глаз

угу  smile 

Цитата(GoldFinch @  16.7.2009,  19:51 Найти цитируемый пост)
писать свою strcpy ради такого случая 

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


Автор: mes 17.7.2009, 14:50
Цитата(mes @  16.7.2009,  22:30 Найти цитируемый пост)
тут подумать надо какую именно логику должна нести функция, чтоб выглядело красиво..

Для си-строки, что то ничего хорошего в голову не приходит. Все таки std::string будет удобнее, только .append лучше заменить на .resize (size,'\0');
хотя бы потому, что входная строка может быть длиннее нормы.


Автор: GoldFinch 17.7.2009, 15:40
да, про resize с двумя аргументами я забыл, так конечно лучше

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)