2013-03-31 2 views
0

В основном я пытаюсь создать Активатор Арены без использования структур, классов или нового оператора для ручного управления памятью. У меня есть определенный размер, пул символов, метод выделения и метод отображения freeMemory.Метод распределения и распределения атак Allacator Arena

Обратите внимание, что pool[0] - это мой индекс, который будет отслеживать, где была заполнена память.

const int size = 50000; 
char pool[size]; 

void start() { 
    pool[0] = 1; 
} 

int freeMemory(void) { 
    int freemem = 0; 
    for(int i = 0; i < size; i++) { 
     if(pool[i] == NULL) { 
      freemem++; 
     } 
    } 
    return freemem; 
} 

void* allocate(int aSize) 
{ 

if(freeMemory() == 0) 
    { 
     out(); 
    } 

else 
{ 
    char* p = NULL; 
    int pos = pool[0]; 
    pool[pos] = (char) a; 
    p = &pool[pos]; 
    pool[0] += a; 
    return((void*) &pool[pos]); 
} 
} 

В main.cpp:

start(); 
long* test1 = (long *) allocate(sizeof(long)); 
cout << freeMemory() << endl; //Returns 49999 
*test1 = 0x8BADF00D; //Breaks here 
cout << freeMemory() << endl; 

Он ломает, когда я пытаюсь использовать 0x8BADF00D, и я считаю, у меня проблемы с инициализацией некоторых из этих переменных тоже.

Необработанное исключение в 0x000515f7 в MemoryManagerC.exe: 0xC0000005: Нарушение прав доступа месте для записи 0x00000004 на 0x8BADF00D

+1

Я не вижу, как вы собрали '* test1 = 0xTESTMEEE' для компиляции. Это действительно ваш код? –

+0

Да. Я имею в виду, что TESTMEEE является просто заполнителем. Я пробовал другие вещи, такие как 0x8BADF00D и FOO, ect. – user99999991

+0

'pool [0]' является символом и будет переполняться после небольшого количества выделенных байтов. Почему бы вам просто не объявить 'size_t', чтобы держать' pos' в качестве поля? И что такое 'a'? – usr

ответ

0

возможная проблема с кодом может быть здесь.

char* pointer; 
for(int i = 0; i < size; i++) 
{ 
    *pointer = pool[i]; 

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

pointer здесь не указывает на что-либо выделенное. Поэтому, когда вы делаете

*pointer = pool[i]; 

Куда следует объединить [i]? Например, допустим, что мы указали такой указатель.

char* pointer = NULL; 

теперь ясно, что

*pointer = pool[i]; 

неправильно. g++ (я заметил) инициализирует указатели на NULL. Таким образом, ваш код будет segfault. VC++ может работать, потому что он не инициализировал NULL pointer. Но вы пишете место памяти, которое не принадлежит вам.

+0

Вы правы, у меня, конечно, была проблема с инициализацией. Но даже после удаления или попытки исправить это все равно дает мне ошибку записи. – user99999991

+0

"g ++ (я заметил) инициализирует указатели на NULL", что в целом неверно. Это совпадение. – usr

1

В приведенном ниже коде содержится множество ошибок.

char* pointer; 
for(int i = 0; i < size; i++) 
{ 
    *pointer = pool[i]; 
    if(pointer != NULL) 
    { 
     pointer = (char*) a; 
     return((void*) i); //return the pointer 
    } 
} 

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

*pointer = pool[i]; 

Вы, вероятно, имел в виду, чтобы скопировать указатель.

pointer = &pool[i]; 

Хотя если сделал значит скопировать указатель из pool массива, это будет всегда быть правдой. Ни один из элементов этого массива не находится по адресу NULL.

if(pointer != NULL) 

Теперь этот код изменяет pointer, чтобы указать на ... более недействительные адреса. Когда a равен sizeof(long), этот размер интерпретируется как адрес памяти. Адрес памяти 0x00000004 скорее всего.

 pointer = (char*) a; 

И тогда это будет возвращать адрес 0x00000000, в вашем случае. Потому что i - 0.

 return((void*) i); //return the pointer 
+0

Вы правы в том, что я перепутал * pointer = pool [i], когда я хотел сказать pointer = & pool [i]; Если проверка была оставлена ​​по ошибке из редактирования, которое я делал. Глубоко я забыл снять его. Однако, после исправления кода немного, чтобы включить индекс, и даже не беспокоиться об усложнении указателя, который я ранее имел, я все еще получаю ошибки записи на 0x00004. Я обновил OP, чтобы показать новые изменения, которые я сделал. – user99999991

+0

@ user2229804 Боюсь, это не ваш настоящий код. 'MM_pool' не определен. Я рекомендую вам скопировать + вставить точную, полную программу в качестве вопроса. У людей будет очень тяжелое время, чтобы помочь вам исправить вашу программу, если то, что вы показываете, на самом деле не является программой, с которой вы столкнулись. –

+0

Ошибка копирования. Я попытался переписать код с нуля и назвал его более конструктивным, но это не помогло, так как я получил ту же проблему. Это программа, я еще не сделал метод удаления. – user99999991

1

Есть некоторые проблемы с выделяют:

char* pointer = NULL; 
int pos = pool[0]; 

pool[0] является char. Он недостаточно велик для хранения индексов всем членам массива.

pool[pos] = (char) a; 

Я не уверен, что вы здесь храните, или почему. Кажется, вы сохраняете размер выделения в пространстве, которое вы выделяете.

pointer = &pool[pos + a]; 

Я думаю, что вы построение указателя на память после выделенной части. Это правильно?

pool[0] += a; 

И здесь вы приращением смещение, которое показывает, сколько из бассейна выделяется, за исключением того, что один char не собирается быть достаточно большим для более чем крошечное количество выделений.

return((void*) &pointer); 

И теперь вы возвращая адрес переменной указателя. Это будет адрес в стеке и небезопасный для использования. Даже если вы только содержание из pointer вместо своего адреса, я думаю, это будет указывать на регион, который вы только что выделили в своем бассейне.

Есть также проблемы с freeMemory. Он сравнивает содержимое пула (char элементов) с NULL. Это говорит о том, что вы думаете, что он содержит указатели, но они всего лишь char s. Непонятно, почему нераспределенные части пула будут равны 0. Вы даже разрешаете освобождение в пуле?

Возможно, вы могли бы объяснить, как вы планируете использовать распределитель? Очевидно, существует разрыв между тем, что вы думаете, что он должен делать, и тем, что он на самом деле делает, но неясно, что вы думаете, что он должен делать, поэтому трудно дать совет. Как вы распределяете пространство в массиве? Вы разрешаете освобождение? Какая информация должна быть закодирована где?


Я просто понял, что выделить использует неопределенные переменную a. Это должно быть то же самое, что параметр aSize? Вот что я здесь принимаю.

+0

Освобождение будет поддерживаться, я просто хотел получить выделение из пути в первую очередь. Указатель, созданный, я пытаюсь сделать точкой после выделения пула памяти. Поэтому, если я выделяю для 0x8BADF00D, он вернет указатель, в котором пул свободен. Что касается пула [0] - что бы вы предложили сохранить мой индекс, который не является глобальной переменной? Моя цель - попытаться сохранить все в массиве пулов без дополнительных переменных. Почему нельзя [0] удерживать местоположение? Шар должен быть достаточно большим? Информация в массиве должна быть только 0x8BADF00D. – user99999991

+0

Я планирую положить строку в нее тоже для string_pointer, но до получения этой ошибки я дошел до int_pointer. – user99999991

+0

Символ 'char' будет удерживать 8 бит на подавляющем большинстве платформ, поэтому наибольшее значение, которое он может удерживать, составляет 255, считая, что оно без знака. Если вы должны сохранить счет в массиве, вы можете зарезервировать для него слоты sizeof (int), а затем использовать memcpy для копирования байтов между началом массива и переменной int. Почему вам не нужны дополнительные переменные? – Weeble

Смежные вопросы