2015-11-20 3 views
0

Я занимаюсь новым/удаленным C++, hashfunction и связанными.C++ указатель, который был освобожден, не был назначен ошибка

Я сделал практику самостоятельно.

У меня есть-структуру, которая

typedef struct student 
{ 
    int id; 
    string fName; 
    string lName; 
    student * nextStudent; 
}Student; 

Тогда в основной функции, я определяю массив студента

Student * table = new Student [10]; 

У меня есть свой хэш-функцию, которая принимает идентификатор и изменить значение 0 -9. Я хочу добавить студента я следующий

void addStudent(int studentId, string firstName, string lastName, Student *table) 
{ 
    // using hash function, convert the id into hashed id 
    int hashedID = hashFunction(studentId); 

     Student * pointer = &table[hashedID]; 

     while(pointer->nextStudent !=NULL){ 
      pointer = pointer->nextStudent; 
     } 

     // once we reach to the student who has NULL in nextStudent 
     // add student 
     Student *tmp = new Student; 
     tmp->id = studentId; 
     tmp->fName = firstName; 
     tmp->lName = lastName; 
     tmp->nextStudent = NULL; 

     // link 
     pointer->nextStudent = tmp; 

} 

Я проверил это, кажется, хорошо.

Проблема есть удаление. Поскольку переменные студента хранятся в динамических memeory, Мне нужно использовать delete.

Ниже приведен мой код.

void deleteAll(Student *table, int len) 
{ 
    for (int i = 0; i < len; i++) 
    { 
     Student* tmp = &table[i]; 

     // delete student info except the last one 
     while (tmp -> nextStudent !=NULL){ 
      Student* tmp2; 
      tmp2 = tmp; 
      tmp = tmp->nextStudent; 
      delete tmp2; 
     } 
    } 
} 

Я посетил каждый студент varialbes ane и сделал удаление. я не могу найти любую проблему в моей делеции Funtion ...

Это то, что я получил после запуска ..

malloc: *** error for object 0x7f85f1404b18: pointer being freed was not allocated 

Я понятие не имею, что я сделал неправильно .. Можете ли вы мне помочь?

EDIT ...

Как вы, ребята, Метиона я добавил "Удалить [] стол" в главном Funtion .. Кроме того, я удалить "удалить TMP" в функции DeleteAll; Я думаю, что «delete [] table» будет обрабатывать эту часть.

Еще не работает ..

Кстати я забыл добавленным initTable функции в исходном сообщении. initTable инициализировать таблицу ...

void initTable (Student *table, int len) 
{ 
    for (int i = 0; i < len; ++i) 
    { 
     table[i].nextStudent = NULL; 
    } 
} 

Спасибо.

+0

Как вы инициализируете «таблицу» после ее выделения? – 1201ProgramAlarm

+7

'table [i]' не выделялся отдельно, он был выделен как часть массива. Все последующие учащиеся в связанном списке могут быть удалены с помощью 'delete', но' table [i] 'необходимо удалить, удалив весь массив (' delete [] table; '). –

+0

@JonathanPotter, который должен быть написан как ответ –

ответ

2

Поле nextStudent никогда не инициализируется, поэтому все 10 элементов, созданных здесь, указывают на неизвестные значения.

Student * table = new Student [10]; 

Это приводит addStudent к петле, пока некоторые pointer->nextStudent не достигнет значения NULL случайно, то перезаписать память, которую он не владеет (если она не попадает в счастливый NULL на первой итерации).

while(pointer->nextStudent !=NULL) { ... } 

«student` структура (кстати, почему ЬурейеЕ?) Должен иметь конструктор по крайней мере сделать это.

student::student() : nextStudent(NULL) { } 


[EDIT] Другой вопрос, что @JonathanPotter должным образом указал в комментарии, что глава каждого из 10 student списков является членом table массива. Это не динамически выделяется и должен не быть отдельно удален.

qucik/легко исправить бы добавить student деструктор рекурсивно удалить дочерние узлы:

student::~student() { if(nextStudent) delete nextStudent; } 

Тогда deleteAll сводилось бы:

void deleteAll(student *table, int len) 
{ 
    for (int i = 0; i < len; i++) 
    { 
     student *tmp = &table[i]; 
     if(tmp->nextStudent) delete tmp->nextStudent; 
    } 
    // this leaves the dynamically allocated table[] in place 
    // to delete it as well, just `delete [] table;` 
} 

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

student::~student() { } 

// ... 

void deleteAll(student *table, int len) 
{ 
    for(int i = 0; i < len; i++) 
    { 
     student *tmp = &table[i]; 

     // delete student info except the *first* one 
     for(student *tmp2; tmp2 = tmp->nextStudent;) 
     { 
      tmp->nextStudent = tmp2->nextStudent; 
      delete tmp2; 
     } 
    } 
    // this leaves the dynamically allocated table[] in place 
    // to delete it as well, just `delete [] table;` 
} 
0

Тогда в основной функции, я определяю массив студента

Student * таблица = новый студент [10];

Прежде всего вы создаете массив учащихся, не участвующих *. И поздно вы пытаетесь удалить не выделенные значения. Это является причиной поведения вашей программы.

Чтобы создать указатель массива указателей Student * вам необходимо следующее:

Student** table = new Student*[10]; 

Чем изменить функции аргументы Student* table в Student** table и продолжить исследования. Также не забудьте удалить стол, используя delete[] table; Удачи.

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