MemSet и MemCopy

Я пишу распределитель памяти, и мне нужен способ хранить целое число внутри куска памяти. Это целое число будет представлять размер блока, чтобы я мог перейти к концу, имея указатель на начало.

Вот мой тестовый пример:

// РЕДАКТИРОВАТЬ: Объявлено пространство для testInt int* testInt = new int;

head_ptr = (char*) malloc(4*1024*1024); // Allocate 4MB

// EDIT: Should have used std::fill and std::copy
memset(head_ptr,23,sizeof(int)); // Set Address head_ptr = 12345

memcpy(testInt,head_ptr,sizeof(int)); // Set testInt = head_ptr

printf("testInt = %i",testInt);

Это вызывает ошибку сегментации во предпоследней строке.

Имеет ли смысл то, что я пытаюсь сделать?

Если да, то каков правильный подход?

Большое спасибо всем за помощь!! Проблема решена :-)


person pws5068    schedule 01.04.2010    source источник
comment
Где определяется testInt? Похоже, здесь ошибка, а не в head_ptr.   -  person Billy ONeal    schedule 01.04.2010
comment
Поскольку testInt действительно указывает на надежное место, memcpy() не работает. Вам нужно напечатать *testInt - и вам нужно его инициализировать: int i; int *testInt = &i;.   -  person Jonathan Leffler    schedule 01.04.2010
comment
Является ли 12345 значением или указателем на значение??   -  person jpyllman    schedule 01.04.2010
comment
@Jonathin, вы делаете хорошее замечание, но я все еще получаю ошибку Seg   -  person pws5068    schedule 01.04.2010
comment
@jpyllman это значение, сейчас я его понизил, чтобы оно не переполнялось   -  person pws5068    schedule 01.04.2010
comment
Переполнение не должно вызывать segfault. И вызов memset здесь не терпит неудачу.   -  person Billy ONeal    schedule 01.04.2010
comment
Хорошо, теперь код использует неинициализированный указатель testInt в вызове memcpy(). Таким образом, вы не знаете, куда вы копируете значение.   -  person jpyllman    schedule 01.04.2010


Ответы (5)


Ответ на исходный вопрос

memset(head_ptr,12345,sizeof(int)); // Set Address head_ptr = 12345

Нет, это не так. Это устанавливает для первых sizeof(int) байтов head_ptr значение 12345, что приведет к переполнению (если вы не используете архитектуру, в которой байт больше 8 бит).

memcpy(testInt,head_ptr,sizeof(int)); // Set testInt = head_ptr

Что такое тестИнт? Целое*? Int? В последнем случае используйте &testInt.

Также из ваших тегов видно, что вы используете C++, а не C. Но ваш код на самом деле просто C, вам действительно следует использовать более безопасные функции и функции C++:

  • memset -> std::fill
  • memcpy -> std::copy
  • маллок -> новый
  • printf -> cout или (лучше) Boost::Format

Ответ на ваше редактирование

int* testInt; — это указатель на целочисленную переменную, но она не инициализирована: она будет указывать на случайную область памяти (мы можем считать ее случайной во всех смыслах и целях, даже если это не так).

Затем memcpy попытается записать в эту случайную область памяти, к которой у вас, скорее всего, нет доступа, и, следовательно, это приведет к ошибке сегментации (это означает, что вы не можете получить доступ к этой области памяти).

person Thomas Bonini    schedule 01.04.2010
comment
Спасибо, Андреас, я очень обязан. - person pws5068; 01.04.2010

Другие прокомментировали неправильное использование memset(3) и memcpy(3), поэтому я отвечу на проблему с распределителем.

Если вы действительно занимаетесь созданием собственного распределителя памяти на C++, взгляните на главу 4 книги Александреску Современный дизайн C++. Он подробно проведет вас через реализацию распределителя небольших объектов. Код доступен как часть Библиотека Локи.

Блин, кому-то нравятся единороги... :)

person Nikolai Fetissov    schedule 01.04.2010

Вы никогда не инициализировали testInt, поэтому ваш вызов memcpy пишет неизвестно куда.

Попробуй это:

int *testInt = malloc(sizeof(int));

person Laurence Gonsalves    schedule 01.04.2010

Если testInt - это просто "int", может ли это быть так, потому что вы передаете его по значению, и оно не изменяется?

person Chris Cooper    schedule 01.04.2010

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

EDIT: Увидев, что вы опубликовали сейчас, вам нужно выделить память для testInt, прежде чем использовать его.

person Billy ONeal    schedule 01.04.2010