Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > memset


Автор: Syltan 23.2.2010, 22:53
Попробовал потренироватся, как работает функция мемсет.
Вот попробовал самый простенький код, но не выдаёт результат 7, хотя все поля 
инициализированны этой функцией семёрками.
Вот исходник:
Код

#include <iostream>
using namespace std;
 
class A{
public:
        int a,b;
        float c;
};
 
int main()
{
A r;
memset(&r,7,sizeof(A));
cout<<r.a;
cin.get();
}
 

Автор: andrew_121 23.2.2010, 23:21
Syltan, 7 - это int. т.е. == 4 байта.
а sizeof(A) == 12 байтам.
мысль улавливаешь?

Добавлено через 2 минуты и 13 секунд
а вообще, memset() можно применять только к POD типам.

Автор: Alexeis 23.2.2010, 23:34
Syltan, к классам memset нужно применять с большой осторожностью. Только в случае если ни у одного из предков не было виртуальных методов и у самого класса тоже. memset(&r,7,sizeof(A)); сработает правильно. Если просмотреть под дебагом память начиная с адреса объекта, то там действительно будут семерки в каждом байте.

Автор: Syltan 23.2.2010, 23:49
То есть в основном их нужно применять к структурам?
Вот попробовал, ну структура выдаёт тоже не 7.
Код

#include <iostream>
using namespace std;

class A{
public:
    int a,b;
    float c;
};

struct m{
    int p,x;
    float k;
};

int main()
{
A r;
m x;
memset(&r,7,sizeof(A));
cout<<r.a<<endl;
memset(&x,7,sizeof(x));
cout<<x.p;
cin.get();
}

Результат:
117901063
117901063

Автор: Alexeis 24.2.2010, 00:06
Цитата(Syltan @  23.2.2010,  22:49 Найти цитируемый пост)
То есть в основном их нужно применять к структурам?

  В С++ структура почти тоже что и класс. 

Цитата(Syltan @  23.2.2010,  22:49 Найти цитируемый пост)
Вот попробовал, ну структура выдаёт тоже не 7.

в переменной a будет 0x07070707 = 117901063 тоже в b, а в c даже посчитать трудно.

Автор: Syltan 24.2.2010, 00:09
Хорошо, скажите в двух словах, какой смысл от memset?

Автор: bsa 24.2.2010, 00:16
Цитата(Syltan @  24.2.2010,  00:09 Найти цитируемый пост)
Хорошо, скажите в двух словах, какой смысл от memset? 
В основном используется для зануления (реже заполнения другими одинаковыми БАЙТАМИ) буферов (непрерывных массивов простейших типов, например char или int).

Автор: Alexeis 24.2.2010, 00:22
Цитата(Syltan @  23.2.2010,  23:09 Найти цитируемый пост)
Хорошо, скажите в двух словах, какой смысл от memset? 

  Ну нулями можно заполнить. Если массив байтов, или символов то можно заполнить чем-то иным отличным от нуля. Вообще, с точки зрения безопасности полезно объект/структуру без VMT занулять. В некоторых случаях это позволяет избежать утечек памяти. Поля указатели обязательно должны зануляться. 

Автор: Syltan 24.2.2010, 00:23
Код

В основном используется для зануления


Для зануления полей в структуре, то ест ьинициализацией кадого поля значением ноль?

Автор: Sosed 24.2.2010, 01:04
Был интересный пример с memset, применяли для сравнения структур, данные ведь располагаются не последовательно, отсюда просто сравнить(==) 2 структуры не получается, помогаем мемсетом:

Код

struct {
  int x;
  double y;
  char z;
} a1, a2;

memset(&a1, 0, sizeof(a)); //зануляем промежутки
memset(&a2, 0, sizeof(a));
...
//работаем с a1, a2


Если надо сравнить используем memcmp(&a1, &a2, sizeof(a1));

Автор: Syltan 24.2.2010, 01:44
Прочитал вот такое:
Код

Функция memset предназначена для заполнения памяти по некоторому адресу некотором значением.

Код

memset(&a1, 0, sizeof(a));

Заполняется память а1 значением ноль?

Ещё вопрос зачем выделять память sizeof?

Автор: Sosed 24.2.2010, 01:57
sizeof размер возвращает
Посмотри размер структуры a1, а потом всех составляющих ее переменных. Различаться будут, значит левые байты есть. Если их не занулить, то неизвестно что там будет, и сравнить не получится.

Автор: lBugl 24.2.2010, 09:50
Цитата

Функция memset предназначена для заполнения памяти по некоторому адресу некотором значением.

угу.
memset(&a1, 0, sizeof(a));

memset это не присваивание объекту или типу значения (к этим словам не придирайтесь =) ). Она записывает в адрес в памяти (1-й параметр)  значение (2-й параметр) и продолжает идти по памяти и заполнять её (сколько? 3-й параметр).... примерно так что ли... =)

Автор: Alexeis 24.2.2010, 10:04
Цитата(Sosed @  24.2.2010,  00:04 Найти цитируемый пост)
Был интересный пример с memset, применяли для сравнения структур, данные ведь располагаются не последовательно, отсюда просто сравнить(==) 2 структуры не получается, помогаем мемсетом:

  На самом деле последовательно, в том смысле что следуют друг за другом в том порядке, в котором их объявили, просто между полями возможны "окна" не несущие ни какой информации. Если объект занулить по полям, то "окна" все равно сохраняют не инициоализированое значения, поэтому побайтовое сравнение одинаковых объектов может не получиться, ведь в окнах остались произвольные значения. Если объект занулить мемсетом, то зануляются и окна, так что становиться возможным проводить побайтовое сравнение.

Автор: Syltan 24.2.2010, 14:24
Код

MEMSET  :offtopic записывает в адрес в памяти (1-й параметр)  значение (2-й параметр) и продолжает идти по памяти и заполнять её (сколько? 3-й параметр).... примерно так что ли... =) 

Код

 записывает в адрес в памяти (1-й параметр)  


Растолкуйте, а то как-то умно написано.

Автор: bsa 24.2.2010, 15:14
Syltan, представь себе, что память это одномерный массив байт. Указатель - это смещение от начала этого массива к конкретному месту, с которого располагается некий кусок данных. Если memset передать это смещение в качестве первого параметра, 0 в качестве второго, и 10 в качестве 3-го, то она заполнит нулями 10 байт начиная с переданного смещения.

Автор: Syltan 24.2.2010, 16:00
Код

memset(&salo,0,sizeof(50));


Это означает что переменная salo,  хранит в себе число состоящее из 50 байт, 
и это число все нули?

Автор: andrew_121 24.2.2010, 16:45
Цитата(Syltan @  24.2.2010,  16:00 Найти цитируемый пост)
Это означает что переменная salo,  хранит в себе число состоящее из 50 байт, 
и это число все нули?

 smile  smile

Добавлено через 1 минуту и 54 секунды
bsa, бесполезно.
таких вопросов, спустя столько написанных постов, я еще не встречал.

Автор: bsa 24.2.2010, 16:51
Syltan,  smile  smile  smile 

начнем с того, что это вообще по идее скомпилироваться не должно. Так как sizeof(50) (сколько байт занимает в памяти число 50 ты хоть сам знаешь?) ничего не сможет вернуть. 
Но даже если бы ты написал memset(&salo, 0, 50), что имеет больше смысла, то это еще не говорит о том, что переменная salo имеет размер 50. Ты вообще перепутал следствие с причиной. Обычно, пишут так: memset(&salo, 0, sizeof(salo)), где salo - зануляемая переменная (не указатель на нее). В твоем же случае, если размер salo меньше 50, то выполнение этой команды приведет не неопределенному поведению программы (скорее всего, это будет просто крах).

Автор: lBugl 24.2.2010, 17:45
memset(p1,p2,p3);
и так))  
р1 -- это адрес в памяти
р2 -- значение которое будем записывать в память
р3 -- количество байт которым будем присваивать значение р2 начиная с р1

как массив, всё правильно объясняли.
к примеру память 1 2 3 4 5 6 7 8 9....
делаем memset(3, 0, 4);
начало памяти считаем с 0-ым индексом т.е. начинается с нуля.
получается память с таким содержимым 1 2 3 0 0 0 0 8 9....

терь по поводу первого параметра. &n -- это не значение переменной, это адрес памяти где она находится. //на сколько я помню =)
проще врядле смогу объяснить...
зы: советую посмотреть операции * и & в си...

Автор: Sosed 24.2.2010, 22:28
Добавим иллюстрации
user posted image
Код

struct {
  int x;
  int y;
  int fuel;
} t34, tz4;
t34.x = 4;
t34.x = 3;
t34.x = 20;
...


ну собственно 
memset(&t34, 0, sizeof(t34)) :
&t34 = 0x0012FE94
sizeof(t34) = 12
После, в ячейках 0x0012FE94, 0x0012FE95, ... , 0x0012FEA5 будут нули, соответственно значения x, y и fuel = 0. Тут структура без дыр.

Автор: xvr 26.2.2010, 13:12
Цитата(Syltan @ 24.2.2010,  16:00)
Код

memset(&salo,0,50);


Это означает что переменная salo,  хранит в себе число состоящее из 50 байт, 
и это число все нули?

После memset - безусловно  smile 
 smile 
- Я изобрел автомат для бритья.
- А как он действует?
- Клиент сует голову в отверстие, и 2 бритвы внутри автомата его бреют
- Но у всех же свой профиль лица!
- Ну. в первый раз, да .....

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