2012-02-16 2 views
2

Это мой первый раз, когда я использовал stackoverflow для вопроса, я прочитал несколько ранее ответов, которые помогли мне в некоторых случаях, поэтому я решил зарегистрироваться, поскольку не могу найти конкретный ответ Я ищу. Недавно я сделал довольно простую систему частиц, которая извергает пару от 100 до 1000 частиц, чтобы увидеть, смогу ли я это сделать, прежде чем я даже начал это делать, я создал простой Связанный список, который использует шаблоны, чтобы я мог использовать его в других программах, если Я так выбираю.Управление обманом памяти с массивами

Недавно, увидев, что мой коллега, играющий с системой частиц, обнаружил, что решил вернуться к моему проекту, чтобы улучшить его. Я просмотрел интернет, чтобы найти небольшой пример, который, по-видимому, бросает идею использования Linked List и вместо этого использует массив и три указателя для управления частицами. Я понимаю большую часть концепции, но по какой-то причине меня избегает.

/// the first particle in the linked list 
    Particle* start=0; 

/// the next free particle 
Particle* last=0; 

/// the end of the memory allocation 
Particle* end=0; 

void SetSize(unsigned int size) { 

    // delete any previous data 
    delete [] start; 

    // allocate new particles 
    last = start = new Particle[size]; 

    // set end 
    end = start+size; 
} 

void AddOne() { 

    // if we have no more memory left for any particles, ignore 
    // the request to creat one. 
    if (!IsFull()) { 
     *last = Particle(); 
     ++last; 
    } 

} 

void EraseOne(Particle* p) { 

    if (!IsEmpty()) { 
     *p = *(--last); 
    } 

} 

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

То, что я не уверен, является битом стирания, я предполагаю из вышеприведенного кода, что «p» становится не частицей, на которую указывает последний указатель, но последним. К сожалению, я понятия не имею, почему это делается таким образом, так как, по-видимому, последний является совершенно живой частицей, но разве это не делает два экземпляра одной и той же частицы?

+0

Делает ли это что-нибудь, что 'std :: vector ' не будет делать, по крайней мере, так же хорошо? –

+0

@ Билл не мог бы вы немного подробнее? Я знаю, что никакая новая частица не создается, а из реализации кажется, что вы просто сделали старую частицу последней, что означало бы, что у вас будет две копии последнего-1. Или я получаю неправильный конец палки? –

+0

@JerryCoffin Возможно, это не так, но я делаю это только для того, чтобы знать, что я могу это реализовать. К сожалению, мой курс по переделке колес - важная часть прохождения курса, поэтому показывая, что я могу реализовать вещи, не полагаясь на существующие библиотеки, является плюсом для любых заданий, которые я выполняю. –

ответ

1

Первое, что вы должны использовать стандартным континентом, а не пытаться использовать половину испеченной ручной реализации. Теперь для интерпретации кода:

Код показывает общий шаблон. В основном вы используете три указателя, один - в начало выделенной памяти (эквивалент begin()), указатель один за последним элементом (эквивалент end() и третий указатель один за последним выделенным блоком (во избежание переполнения).

С учетом этого интерпретация функций не является трудной. В частности, AddOne (аналогично push_back, но без роста буфера) обновляет первый элемент за пределами конца и увеличивает указатель на один за новым новым элементом.

Начиная с EraseOne в основном выполняет обратную операцию: сначала он уменьшает указатель (так что теперь предыдущий элемент находится за пределами допустимого диапазона) и t купит этот элемент (помните, что указатель ссылается на один за его пределами)

+0

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

+0

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