Вопрос по C++

Для тех, кто хочет сделать мир лучше.
Сообщение
Автор
Lev2008
Лейтенант
Лейтенант
Сообщения: 221
Зарегистрирован: 08.11.2008

#76 Сообщение 20.09.2010, 13:40

Спору нет. Привыкайте. :)
При работе со строками, memset - это и есть мнимое исключение из правил.
Приведите пример, работы со строками, когда memset необходим и обязателен.

Аватара пользователя
NiGHt-LEshiY
Полковник
Полковник
Сообщения: 10258
Зарегистрирован: 13.06.2008
Откуда: Россия
Благодарил (а): 752 раза
Поблагодарили: 2667 раз
Контактная информация:

#77 Сообщение 20.09.2010, 14:10

В си есть функции, которые не следят, чтобы строки заканчивались на '\0'
К тому же, вовсе не обязательно использовать стандартные функции при работе со строками. Вдруг нужно работать как-то иначе?

Код: Выделить всё

char str[256];
str[0] = '\0';
При попытке записать три символа, получим три нужных символа + 253 символа-мусора.
Кодекс поведения участников сообщества — обязательно к прочтению.
Просьба присылать сообщения об ошибках в ЛС.

Lev2008
Лейтенант
Лейтенант
Сообщения: 221
Зарегистрирован: 08.11.2008

#78 Сообщение 20.09.2010, 14:22

NiGHt-LEshiY писал(а):В си есть функции, которые не следят, чтобы строки заканчивались на '\0'
Если они не следят за окончанием на 0 тогда разницы сделан memset или просто [0]=0 нет. Ну и, пример приведите.
NiGHt-LEshiY писал(а):

Код: Выделить всё

char str[256];
str[0] = '\0';
При попытке записать три символа, получим три нужных символа + 253 символа-мусора.
Пример записи трех символов приведите.

Аватара пользователя
NiGHt-LEshiY
Полковник
Полковник
Сообщения: 10258
Зарегистрирован: 13.06.2008
Откуда: Россия
Благодарил (а): 752 раза
Поблагодарили: 2667 раз
Контактная информация:

#79 Сообщение 20.09.2010, 14:28

Код: Выделить всё

str[0] = 'w';
str[1] = 'o';
str[2] = 'w';
Кодекс поведения участников сообщества — обязательно к прочтению.
Просьба присылать сообщения об ошибках в ЛС.

Lev2008
Лейтенант
Лейтенант
Сообщения: 221
Зарегистрирован: 08.11.2008

#80 Сообщение 20.09.2010, 14:31

И что мешает сделать после этого

Код: Выделить всё

str[3] = 0;
?
Раз уж вы используете такой стиль программирования, как установка каждого символа по отдельности.

PS Поймите меня правильно: не надо меня толпой убеждать, что memset это "православно". Я просто говорю (и даже не вам лично, а тому человеку, что приводил примеры неработающего кода), что надо понимать что вы делаете. Если вы готовите буфер для функции, которая требует на входе нуль-терминированную строку, то и делайте нуль-терминированную строку. Если кто-то всё равно хочет занулять всё - ну зануляйте, но это излишне.

PSS
NiGHt-LEshiY писал(а):В си есть функции, которые не следят, чтобы строки заканчивались на '\0'
Не забудьте название функции и пример использования привести.

Аватара пользователя
NiGHt-LEshiY
Полковник
Полковник
Сообщения: 10258
Зарегистрирован: 13.06.2008
Откуда: Россия
Благодарил (а): 752 раза
Поблагодарили: 2667 раз
Контактная информация:

#81 Сообщение 20.09.2010, 14:54

Lev2008
Может лучше залезть в доки и найти самому?
Суть в том, что memset - "выделение" места под строку. Это хороший стиль.
Кодекс поведения участников сообщества — обязательно к прочтению.
Просьба присылать сообщения об ошибках в ЛС.

Fire666
Эксперты no-Steam
Эксперты no-Steam
Сообщения: 2600
Зарегистрирован: 15.02.2007
Откуда: Москва
Благодарил (а): 2 раза
Поблагодарили: 43 раза
Контактная информация:

#82 Сообщение 20.09.2010, 15:08

Lev2008, да я согласен, memset не обязателен, но он ведь не может принести вреда, а вот подстраховаться от засорения буфера мусором лишним не будет.
Не забудьте название функции и пример использования привести.
Насчет стандартных хз, а вот в движке GoldSRC для вызова функции кеширования модели 0 просто необходим.

Аватара пользователя
GanGSISoft
Полковник
Полковник
Сообщения: 1430
Зарегистрирован: 27.03.2008
Откуда: Бацькаўшчына
Благодарил (а): 2 раза
Поблагодарили: 3 раза
Контактная информация:

#83 Сообщение 20.10.2010, 22:21

Вот наткнулся на фукцию для которой memset необходим, ну или надо самому 0 ставить, что не всегда может оказаться удобно, да и ошибиться может оказаться легко, если код не простейший.
Функция это fread, если использовать считанные данные как строка.(Она не конкретно под строки, поэтому ноль в конце она никак не может ставить).
------------------
Ещё вопрос. Чем отличается данные записи:
1)char buf[100]; memset(buf,0,101)
2)char *buf=new char[100]; memset(buf,0,101)
3)char *buf=new char; memset(buf,0,101);
4)short int buf[100]; memset(buf,0,101);
Во всех ли случаях есть смысл в memset? И можно ли использовать запиь №3?

Добавлено спустя 5 минут 54 секунды:
И ещё, если записать char s[10]; memset(s,0,20); То оно перезапишет байты которые следуют за s, или ничего не сделает? Что короче сделается?
Последний раз редактировалось GanGSISoft 20.10.2010, 22:16, всего редактировалось 1 раз.

Fire666
Эксперты no-Steam
Эксперты no-Steam
Сообщения: 2600
Зарегистрирован: 15.02.2007
Откуда: Москва
Благодарил (а): 2 раза
Поблагодарили: 43 раза
Контактная информация:

#84 Сообщение 20.10.2010, 23:01

char *buf=new char; memset(buf,0,101);

ты же выделяешь память размером sizeof( char ), а не 101.

Насчет последнего вопроса. я не помню, что там в винде с доступами к памяти, но имхо, memset зачистит столько сколько ему указали, то есть, не только сам char, но и то, что идет после.

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

Аватара пользователя
GanGSISoft
Полковник
Полковник
Сообщения: 1430
Зарегистрирован: 27.03.2008
Откуда: Бацькаўшчына
Благодарил (а): 2 раза
Поблагодарили: 3 раза
Контактная информация:

#85 Сообщение 21.10.2010, 01:03

Fire666 писал(а):char *buf=new char; memset(buf,0,101);

ты же выделяешь память размером sizeof( char ), а не 101
Я таким образом хочу выделить память в 101 байт под buf. Но я думаю что так делать нельзя, так как memset не выделяет а чистит память, но может вдруг и можно. Хочу уточнить

Аватара пользователя
NiGHt-LEshiY
Полковник
Полковник
Сообщения: 10258
Зарегистрирован: 13.06.2008
Откуда: Россия
Благодарил (а): 752 раза
Поблагодарили: 2667 раз
Контактная информация:

#86 Сообщение 21.10.2010, 07:34

char *buf=new char; // создает динамический char, а не массив
memset(buf,0,101); // а тут попытка очистить 101 байт, а не 100.

Код: Выделить всё

char *buf = new char [100];
memset(buf,0,100);
Кодекс поведения участников сообщества — обязательно к прочтению.
Просьба присылать сообщения об ошибках в ЛС.

Аватара пользователя
x_000
Полковник
Полковник
Сообщения: 4889
Зарегистрирован: 25.02.2008
Откуда: Deutsches Reich
Благодарил (а): 6 раз
Поблагодарили: 18 раз

#87 Сообщение 21.10.2010, 14:25

опять вы со своими петушиными методиками
я же вам сказал способ для выделения памяти
x_000 писал(а):

Код: Выделить всё

char *pointer;

__asm {
   sub esp, size
   mov pointer, esp
}
вот он, лучший способ же

Аватара пользователя
NiGHt-LEshiY
Полковник
Полковник
Сообщения: 10258
Зарегистрирован: 13.06.2008
Откуда: Россия
Благодарил (а): 752 раза
Поблагодарили: 2667 раз
Контактная информация:

#88 Сообщение 21.10.2010, 16:24

x_000
Wrong. Вставки не нужны здесь. Это не mencoder, где вставки _необходимы_
Кодекс поведения участников сообщества — обязательно к прочтению.
Просьба присылать сообщения об ошибках в ЛС.

Аватара пользователя
x_000
Полковник
Полковник
Сообщения: 4889
Зарегистрирован: 25.02.2008
Откуда: Deutsches Reich
Благодарил (а): 6 раз
Поблагодарили: 18 раз

#89 Сообщение 21.10.2010, 19:09

NiGHt-LEshiY
что ты тут закукарекал
выделение стековой памяти ассемблерной вставкой - самый лучший способ, потому что самый быстрый и есть возможность задавать размер динамический
а все остальные - петухи, вот так вот

Аватара пользователя
GanGSISoft
Полковник
Полковник
Сообщения: 1430
Зарегистрирован: 27.03.2008
Откуда: Бацькаўшчына
Благодарил (а): 2 раза
Поблагодарили: 3 раза
Контактная информация:

#90 Сообщение 21.10.2010, 23:02

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

Код: Выделить всё

int LoadFromFile(wchar_t *filename,byte *buf)
{
	FILE *fp;
	_wfopen_s(&fp,filename,L"r");
	if(fp==NULL){return -1;}
	long int l=_filelength(_fileno(fp));
	buf=new byte[l+1];
	memset(buf,0,l+1);
	fread(buf,l,1,fp);
	fclose(fp);
	return l;
}

............
byte *fl=new byte;
LoadFromFile(filename,fl));
......
В fl ничего не изменяется после выполнения функции LoadFromFile, если в fl записать какойнибудь текст, то после LoadFromFile ничего не изменится.
Если сделать так,
.....
byte *fl=new byte[1000000000];
LoadFromFile(filename,fl));
.....
А в функции убрать строку buf=new byte[l+1];, то всё работает, но выделять памя до выполнения функции LoadFromFile не удобно, надо отдельно смотреть размер файла.

Добавлено спустя 2 минуты 39 секунд:
При отладке видно что buf содержит содержимое файла
(пробовал чтото сделать с кодом от x_000, но я там слабо понимаю, и получаю ошибку
LoadFromFile: неуправляемую функцию невозможно компилировать с параметрами /clr:pure или /clr:safe Встроенный машинный код на языке ассемблера в управляемом коде не поддерживается
)
Последний раз редактировалось GanGSISoft 21.10.2010, 23:04, всего редактировалось 1 раз.

Ответить