2016-01-05 3 views
-1

EDITED: добавлен конструктор и деструктор.C++ delete [] calls destructor

EDIT: это утечка:

c:\users\sijaan\desktop\1\starray.cpp(61) : {148} normal block at 0x007C0910, 40 bytes long. 
Data: <  h |  > C8 00 00 00 02 00 00 00 68 09 7C 00 CD CD CD CD 
c:\users\sijaan\desktop\1\starray.cpp(43) : {145} normal block at 0x007C04B0, 40 bytes long. 
Data: <d   {  > 64 00 00 00 01 00 00 00 A8 E2 7B 00 CD CD CD CD 
c:\users\sijaan\desktop\1\starray.cpp(24) : {143} normal block at 0x007C0150, 816 bytes long. 
Data: < X {   > 80 00 00 00 58 E1 7B 00 CE CD CD CD CE CD CD CD 
Object dump complete. 

Я пытаюсь создать новый объект после каждого вызова для этой функции:

bool StArray::addCS_Course(int StudentID, int CourseID, char * CourseName, int HwNum, double HwWeigh, int Flag, char * BookName) 
{ 
    for (int i = 0; i < MAX_STUDENT_NUM; i++) { 
     if (StArray_[i] == NULL) continue; 
     if (StArray_[i]->getID() == StudentID) { 

      CS_Course* New_CS = new CS_Course(CourseID, CourseName, HwNum, HwWeigh, Flag, BookName); 

      StArray_[i]->addCS_Course(New_CS); 
      return true; 
     } 

    } 
     return false; 
} 

я должен использовать новый, чтобы сделать это? или сам конструктор делает объект для использования вне этой функции?

Вот объявление класса:

class CS_Course : public Course { 

public: 
    /*Interface functions*/ 
    /* ***************************************************** 
    Function: CS_Course 
    Abstract: constructor 
    Parameters: 
     Course_Id : course number 
     Course_Name : course name 
     Hw_Num : homeworks number 
     Hw_Weigh : the weigh of the homeworks 
    Return Value: 
    ***************************************************** */ 
    CS_Course(int Course_ID, char* Course_Name, int Hw_Num, double Hw_Weigh, int flag, char* BookName); // constructor 
    ~CS_Course(); 

private: 
    int flag_; 
char* BookName_; 

Я спрашиваю это потому, что когда я удалить строку CourseName и BookName, I «» до сих пор новый выделенный объект, который не имеет ничего. Тогда я делаю это: delete[] pCSC[j]; У pCSC есть указатели на CS_Course. Но я получаю сообщение об ошибке, потому что это удаление вызывает деструктор CS_Course, который пытается уничтожить имя курса, которое я уже уничтожил.

Это конструктор:

CS_Course::CS_Course(int Course_ID, char * Course_Name, int Hw_Num, double Hw_Weigh, int flag, char * BookName) 
    :Course(Course_ID, Course_Name, Hw_Num, Hw_Weigh), flag_(flag) 
{ 
    BookName_ = new char[strlen(BookName) + 1]; 
    strcpy(BookName_, BookName); 
} 

и это деструктор:

CS_Course::~CS_Course() 
{ 
    delete[] BookName_; 
} 
+0

Вы почти никогда не должны использовать в своем коде 'new' /' new [] 'или' delete'/'delete []'. У вас есть действительно веская причина? –

+0

Замечание: вы делаете (в большинстве случаев) что-то не так, когда вы помещаете выделенную память в контейнер (если вам нужен полиморфизм, вы должны использовать std :: unique_ptr или std :: shared_ptr) –

+0

Тот факт, что вы не используете стандартные типы (например, 'std :: vector' или' std :: string') предполагает, что вы должны прочитать хороший учебник. Во всяком случае, в общем, избегайте использования 'new' и' delete', если это возможно. Если вы это сделаете, используйте интеллектуальные указатели, а не необработанные указатели. Однако, интересно, какое отношение к вам тема «delete [] вызывает деструктор». Если вы можете, пожалуйста, также извлеките минимальный пример, см. Руководство по публикации для получения дополнительной информации. –

ответ

0

new здесь необходимо, так как вы передаете указатель на вновь созданный объект. Если вы создаете локальную переменную и передаете ее, она не будет доступна вне этой функции.

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

+0

Ну, это то, что я пытаюсь сделать, когда мне это больше не нужно. Но это дает мне ошибку, что я удаляю nullptr. –

+0

Добавлены определения const и destr. –

0

Вы привыкли к C и теперь переключаетесь на C++, не так ли?

EDIT:

Вы часто, вам не нужно выделять что-то вообще:

class CS_Course : public Course { 
public: 
    CS_Course(int Course_ID, char* Course_Name, int Hw_Num, double Hw_Weigh, int flag,char* BookName) 
    :Course(Course_ID, Course_Name, Hw_Num, Hw_Weigh), flag_(flag), BookName(BooName) 
    { 
    } 
private: 
    int flag_; 
    std::string BookName_; 
}; 

Выделяя структуры данных функций является то, что вы не можете избежать в C, но в C++! Никогда не используйте raw new s в современном коде C++!

Используйте новые умные указатели, такие как std::unique_ptr и std::shared_ptr.

Они позволяют вам делать то, что вы не испытываете, без каких-либо проблем с двойным удалением.

Также старайтесь не использовать встроенные типы данных C. Используйте std::string вместо char*, то есть const std::string & вместо const char* и std::vector или std::array вместо встроенных массивов!

+0

Я только что перешел на C++ (2 недели назад). Мне не разрешено использовать интеллектуальные указатели –

+0

Но вам разрешено использовать 'std :: string', не так ли? – Superlokkus

+0

не разрешено использовать std: string –