2013-03-31 3 views
0

Я пытаюсь выяснить реализацию очереди на основе массива в C++. На данный момент я просто пытаюсь инициализировать массив с размером, зависящим от того, что вводит пользователь. У меня есть класс Queue следующим образом:Указатель на массив не работает по назначению

Queue.h: #include

using namespace std; 

class Queue { 

    private: 
     int *ptrtoArray; 
     int arraysize; 
     int data; 
    public: 
     Queue(int size); 
     Queue(); 
     void print(); 


}; 

Queue.cpp:

#include "Queue.h" 

Queue::Queue() { 

} 
Queue::Queue(int size) { 
    int theQueue[size]; 
    arraysize = size; 
    ptrtoArray = &theQueue[0]; 

    for (int i=0;i<size;i++) { 
     theQueue[i] = -1; 
    } 
    cout << "("; 
    for(int i=0;i<size;i++) { 

     cout << ptrtoArray[i] << ","; 
    } 
    cout << ")" << endl; 
} 
void Queue::print() { 
    cout << "("; 
    for(int i=0;i<arraysize;i++) { 
     cout << ptrtoArray[i] << ","; 
    } 
    cout << ")" << endl; 
} 

main.cpp:

#include <iostream> 
#include "Queue.h" 

using namespace std; 

const string prompt = "queue> "; // store prompt 

Queue *queue; 

void options(){ 
    string input; // store command entered by user 
    cout << prompt; // print prompt 
    cin >> input; // read in command entered by user 
    int queuesize,num; 
    while(input != "quit") { // repeat loop as long as user does not enter quit 
     if (input == "new") { // user entered ad 
      cin >> queuesize; 
      queue = new Queue(queuesize); 
     } else if (input == "enqueue"){ //user entered remove 
     } else if (input == "dequeue"){ //user entered remove 
     } else if (input == "print"){ //user entered quit 
      queue->print(); 
     } else { // no valid command has been selected 
      cout << "Error! Enter add, remove, print or quit." << endl; 
     } 
     cout << prompt; // repeat prompt 
     cin >> input; // read new input 
    } 
}//options 

/** 
* Main function of the program. Calls "options", which handles I/O. 
*/ 
int main() { 
    options(); 
    return 0; 
} 

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

queue> new 5 
(-1,-1,-1,-1,-1,) 
queue> print 
(134516760,134525184,-1081449960,4717630,134525184,) 
queue> 

Таким образом, на данный момент я просто хочу, чтобы функция печати(), чтобы показать мне, что массив содержит только -1 в каждом элементе. Мои знания указателей очень ограничены, поэтому, если вы могли бы помочь мне понять, что я делаю неправильно, это было бы здорово!

ответ

2
int theQueue[size]; 
arraysize = size; 
ptrtoArray = &theQueue[0]; 

Выделяет статический массив theQueue, который будет освобожден, когда возвращается конструктор. Вы должны вместо этого выделить динамический массив с new

arraysize = size; 
ptrtoArray = new int[size]; 

Не забудьте удалить его в вас деструктора (или раньше, если это не нужно больше).


EDIT

Статическая

int theQueue[size]; 

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

Преимущества быстрее, вам не нужно явно освобождать его, чтобы избежать утечек.

Dynamic

ptrtoArray = new int[size]; 

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

delete[] ptrtoArray; 

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

+0

Это сработало, спасибо! Не могли бы вы объяснить, может быть, немного более подробно различие между двумя способами объявления этого? В частности, почему использование нового в этом случае имеет более широкий охват. – dmarzio

+0

Я уверен. Я отредактирую ответ. – 2013-03-31 18:28:47

+0

Благодарим вас за разъяснение. Я понимаю это сейчас. – dmarzio

3

Вы объявляете свой массив в локальной области действия, а затем теряете его, когда он выходит из области видимости, но указатель по-прежнему указывает на его адрес в памяти, который знает, что с ним будет, как вы узнали , Попробуйте:

ptrToArray = (int *) malloc(sizeof(int) * size); 

или new ключевое слово:

ptrToArray = new int[size]; 
+0

Куда бы это точно? – dmarzio

+0

В вашем конструкторе очереди: вместо того, чтобы объявить его как другой int [] с именем theQueue, а затем используя адрес этого, замените все это только на строку ptrToArray =. Конечно, сохраните arraysize = part! –

0

Это на самом деле ожидается. См., Член ptrtoArray из class Queue указывает на переменную функции-области, которая не будет доступна на протяжении всего жизненного цикла программы. Вот, это ваш конструктор. Так ptrtoArray будет указывать на совершенно случайном месте памяти, то есть это то, что называется, как «дикий указатель»

Смотреть это: https://stackoverflow.com/a/11137525/1919302 для лучшего представления о разнице между Scope и время жизни переменной и почему ваш выход так оно и есть.

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