2016-03-16 4 views
-2

Моя программа должна взять слово от пользователя (неизвестной длины), а затем создать связанный список, где каждый узел должен содержать один символ. Он работает с заранее объявленной слова, но я получаю проблемы, если я пытаюсь упростить cin >> word:Повреждение стека с использованием связанного списка

Стек вокруг переменной «» ул была повреждена.

Любая помощь будет радушна.

#include <iostream> 
#include <iomanip> 
#include <stdio.h> 

using namespace std; 

struct slistEl 
{ 
    slistEl * next; 
    char data; 
}; 

unsigned l_size(slistEl * head) 
{ 
    unsigned c = 0; 
    slistEl * p = head; 

    if (p) 
     do 
     { 
      c++; 
      p = p->next; 
     } while (p != head); 
    return c; 
} 


void l_printl(slistEl * head) 
{ 
    slistEl * p; 

    cout << setw(3) << l_size(head) << " ["; 
    p = head; 
    if (p) 
     do 
     { 
      p = p->next; 
      cout << " " << p->data; 

     } while (p != head); 
    cout << " ]\n\n"; 
} 

void l_push(slistEl * & head, char v) 
{ 
    slistEl * p = new slistEl; 

    p->data = v; 
    if (head) 
    { 
     p->next = head->next; 
     head->next = p; 
    } 
    else 
     p->next = p; 
    head = p; 
} 

void l_pop(slistEl * & head) 
{ 
    if (head) 
    { 
     slistEl * p = head->next; 
     head->next = p->next; 
     if (p->next == p) 
      head = NULL; 
     delete p; 
    } 
} 

int main() 
{ 
    slistEl * head = NULL; 

    char str[] = "abcdefgh"; // pre-declarated word 

    //cin >> str; //program should take word from user 

    for (int i = 0; str[i] != '\0'; i++) 
    { 
     l_push(head, str[i]); 
     l_printl(head); 
    } 

    system("PAUSE"); 
    return 0; 
} 
+0

Какой длины слова вы вводите в консоль? – Matt

+0

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

ответ

0

Это потому, что char str[] - это массив, созданный с правильной длиной для переданного ему литерала, а массивы C++ не расширяются динамически.

Если я заменю определение str на: char* str = new char[256];, то программа будет выполнена отлично (если вы не дадите ей больше 256 символов).

Лучшим способом для этого было бы использовать C++, используя getline и string.

std::string str; 
std::getline(cin, str); 

for (int i = 0; str[i] != '\0'; i++) 
{ 
    l_push(head, str[i]); 
    l_printl(head); 
} 

В качестве альтернативы добавить символы, как вы читаете из cin, хотя это и не оканчиваются на переводы строк, как я ожидал.

char c; 
while (cin >> c) 
{ 
    l_push(head, c); 
    l_printl(head); 
} 
+0

спасибо за вашу помощь, но я не могу использовать строку или предварительно объявить длину слова (это академическая проблема) –

+0

@JackPatch, в этом случае просто читайте символы из cin напрямую, я обновил ответ. – Matt

+0

спасибо!он работает для меня, теперь мне нужно просто понять, как выйти из этого «while (cin >> c)» loop –

1

В вашем методе l_push(), вы выделяете новый узел:

void l_push(slistEl * & head, char v) 
{ 
slistEl * p = new slistEl; 

p->data = v; 

Теперь несколько строк ниже, мы имеем следующее:

p->next = p; 

Как вы думаете, что делает смысл установить указатель нового узла next, чтобы указать на себя?

Очевидно, что нет, и это ваша проблема.

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

+0

Таким образом, OP имеет последний элемент в списке, указывающий на первый, затем использует это для определения конца списка. Это странно, но код работает так, как ожидалось. – Matt

+0

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

+0

Это не будет хорошо связанный список, каждый узел в списке указывает на себя. –

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