Delete scalar ошибка c

Your copy constructor does a shallow copy. So, now you have two objects that both have the same recording pointer.

You should either do a deep copy, or ensure the ownership is properly transferred (by using something like std::unique_ptr<Recording> if C++11 is available.

See This question on the difference between deep and shallow copies.

Let’s look at some examples:

class ABadCopyingClass
{
public:
   ABadCopyingClass()
   {
       a_ = new int(5);
   }

   ~ABadCopyingClass()
   {
       delete a_;
   }

private:
    int* a_;   
};

The above class is bad because the default copy constructor and assignment operator will perform a shallow copy, and lead to two objects both thinking that they own the underlying a_ object. When one of them goes out of scope, the a_ will be deleted, and the other one will be left with a dangling pointer that will eventually lead to a crash.

class ABetterCopyingClass
{
public:
    ABetterCopyingClass()
       a_(new int(5))
    {
    }

    ABetterCopyingClass(const ABetterCopyingClass& r)
    {
        a_ = new int(*r.a_);
    }

    ABetterCopyingClass& operator=(const ABetterCopyingClass& r)
    {
        // in the case of reassignment...
        delete a_;

        a_ = new int(*r.a_);
        return *this;
    }

    ~ABetterCopyingClass()
    {
        delete a_;
    }

private:
    int* a_;    

};

This class improved our situation a little (note, that the normal error checking is left out in this simple example). Now the copy constructor and assignment operator properly perform the necessary deep copying. The drawback here is the amount of boilerplate code we had to add — it’s easy to get that wrong.

class ACannonicalCopyingClass
{
public:
   ACannonicalCopyingClass()
      : a_(new int(5))
   {
   }

   ACannonicalCopyingClass(ACannonicalCopyingClass&& moved_from)
   {
       a_ = std::move(moved_from.a_);
   }
private:
   std::unique_ptr<int> a_;
};

This example (C++11 only) is even better. We’ve removed a significant amount of boilerplate code, however the semantics here are a bit different. Instead of deep copying, we get in this case transfer of ownership of the underlying a_ object.

The easiest version (C++11 only) to implement is the version that provides shared ownership of the underlying a_ object. This is the version that is most similar to your provided example, with the added bonus that it does not cause a crash.

class ASharedCopyingClass
{
public:
   ASharedCopyingClass()
      : a_(std::make_shared<int>(5))
   {
   }

private:
    std::shared_ptr<int> a_;
};

This version can be copied at will, and the underlying a_ object will happily be reference counted. The last copy to go out of scope will set the reference count to 0, which will trigger the memory deallocation.

Цитата
Сообщение от argcargv
Посмотреть сообщение

Т.е. ты несёшь неизвестно откуда взявшуюся чушь, а другие должны бегать и искать откуда ты её берёшь?

нет никаких «т.е.»
ты сделал вывод исходя из собственных фантазий своего бреда.

а мои тезисы опираются на стандарт,
в частности, опираются на материал, доступный по ссылкам, который ты привел в #2
и самое главное: подтверждаются реальной практикой.

Цитата
Сообщение от argcargv
Посмотреть сообщение

Да, invalid pointer value не обязательно единственное значение. Их неопределённое число.

это не просто «не обязательно единственное значение» — это вообще не конкретное значение.
любое значение может стать «invalid pointer value».

одно и тоже значение: сегодня ещё валидное, а завтра уже не_валидное.

Цитата
Сообщение от argcargv
Посмотреть сообщение

Ну тупишь пока только ты, называя значение характеристикой значения.

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

Цитата
Сообщение от argcargv
Посмотреть сообщение

считаю что в C++ происходит запись в указатель только потому что я прочитал что так считают сишники.

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

но даже если принять за истину тезис, что зомби-указатели чего то там должны.
что с того?
это не даёт тебе никаких оснований считать,
что на самом деле происходит с указателями с++.

твои горячо любимые сишники нигде не писали, что в с++ по указателю происходит какая то запись.
так с какого фига ты сделал такой вывод?

эй ау, у тебя какие то проблемы с логикой?

Цитата
Сообщение от argcargv
Посмотреть сообщение

Нет такого значения, как «адрес объекта». Есть «указатель на объект».

такое впечатление, что ты деградируешь.
раньше ты настолько тупым не был.

указатель на объект — это тип данных.
его значение — адрес объекта.

я сейчас напишу фразу, которую без труда сможет понять любой,
даже начинающий программист с++:

нужно взять адрес объекта, и поместить его в указатель

теоретически: даже ты должен суметь понять.

Цитата
Сообщение от argcargv
Посмотреть сообщение

Мне вполне понятна элементарная вещь: в теме значений указателей ты плаваешь.

моя скоромная персона тебя вообще касаццо не должна.
ты со своими мозгами разберись для начала.

ты уже понял, что такое «валидный указатель» ?

Цитата
Сообщение от argcargv
Посмотреть сообщение

Еды тебе больше не будет. Можешь продолжать нести чушь сколько угодно.

обязательно расскажи про это своему психиатру.

заодно расскажи ему,
что ты таки проигнорировал объективную реальность (код #11),
ведь она противоречит твоей шизоидной теории.

Задача программы: считать из файла строку, каждое слово из которой необходимо присвоить отдельному элементу массива. Далее, найти 3 самых длинных и 3 самых коротких слова, а затем вывести все слова в порядке, обратном алфавитному. Все задачи написанная мною программа решает, но я не могу очистить память. Проблема в куске программы, в котором элементам массива b присваивается строка из переменной token (все это в цикле while). Именно после сей действия не получается воспользоваться delete[]. Все массивы уже сделал одной размерности, но все равно не помогло. В чем может быть проблема? Код прилагаю ниже. Заранее спасибо!

#define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"
#include <stdlib.h>
#include <stdbool.h>
#include <iostream>
#include <locale.h>
#include <windows.h>
#include <ctype.h>
#include <fstream>
#include <malloc.h>
#include <conio.h>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>

using namespace std;

void bigswap(int i, int len, int biggest[]) {
    if (len > biggest[0]) {
        biggest[4] = biggest[2];
        biggest[5] = biggest[3];
        biggest[2] = biggest[0];
        biggest[3] = biggest[1];
        biggest[0] = len;
        biggest[1] = i - 1;
    }
    else {
        if (len > biggest[2]) {
            biggest[4] = biggest[2];
            biggest[5] = biggest[3];
            biggest[2] = len;
            biggest[3] = i - 1;
        }
        else {
            if (len > biggest[4]) {
                biggest[4] = len;
                biggest[5] = i - 1;
            }
        }
    }
}
void littleswap(int i, int len, int little[]) {
    if (len < little[0]) {
        little[4] = little[2];
        little[5] = little[3];
        little[2] = little[0];
        little[3] = little[1];
        little[0] = len;
        little[1] = i - 1;
    }
    else {
        if (len < little[2]) {
            little[4] = little[2];
            little[5] = little[3];
            little[2] = len;
            little[3] = i - 1;
        }
        else {
            if (len < little[4]) {
                little[4] = len;
                little[5] = i - 1;
            }
        }
    }
}
void gettext(char **b, int kolslov) {
    printf("Слова, выведенные в порядке, обратном алфавитному:nn");
    for (int i = 0; i < kolslov; i++) {
        printf("%sn", b[i]);
    }
    printf("nn");
}
void minusswap(char **b, int kolslov) {
    for (int i = 0; i < (kolslov - 1); i++) {
        for (int j = i + 1; j < kolslov; j++) {
            if ((int)b[i][0] < 91) {
                b[i][0] = (char)((int)b[i][0] + 32);
            }
            if ((int)b[j][0] < 91) {
                b[j][0] = (char)((int)b[j][0] + 32);
            }
            if (strcmp(b[i], b[j]) < 0) swap(b[i], b[j]);
        }
    }
}
void initialization(int biggest[], int little[]) {
    for (int i = 0; i < 6; i++) {
        biggest[i] = -1;
        little[i] = 100;
    }
}


int main() {

    char **b, *buffer, *token, delims[] = " n.,!?/<>|)(*:;"";
    const int len_text = 300;
    int max_len = 0, size_len = 0, Nslov = 0, kolslov = 0, menu = 0;
    int biggest[6], little[6];
    FILE *load = NULL;

    setlocale(LC_ALL, "Russian");
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);

    printf("Данная программа считывает ваш текст из файла, находит в нем три самых длинных и три самых коротких слова, а также располагает все слова в порядке, обратном алфавитному.nnn");
    system("pause");
    system("cls");

    for (;;) {

        load = fopen("FILE.txt", "r");
        fscanf_s(load, "%in", &kolslov);
        initialization(biggest, little);

        b = new char*[kolslov];
        /*for (int i = 0; i < kolslov; i++) {
            b[i] = new char[30];
        }*/

        buffer = new char[300];
        token = new char[300];

        fgets(buffer, len_text, load);
        printf("Первоначальный текст:nn%snnnНайденные слова:nn", buffer);

        token = strtok(buffer, delims);

        int i = 0;

        while (token != NULL)
        {
            int len = strlen(token);
            b[i] = new char[300];
            b[i] = token;
            Nslov++;
            printf("%sn", b[i]);
            i++;
            bigswap(i, len, biggest);
            littleswap(i, len, little);
            token = strtok(NULL, delims);
        }

        printf("nnТри самых длинных слова в данном тексте:nn%sn%sn%snn", b[biggest[1]], b[biggest[3]], b[biggest[5]]);
        printf("nТри самых коротких слова в данном тексте:nn%sn%sn%snnn", b[little[1]], b[little[3]], b[little[5]]);

        minusswap(b, kolslov);
        gettext(b, kolslov);

        system("pause");

        for (int i = 0; i < kolslov; i++) {
            printf("n%sn", b[i]);
            delete[] b[i];
        }
        delete[] b;

        fclose(load);
        system("pause");
        system("cls");
    }
    system("pause");
}

Код того места, где появляется проблема, которая в дальнейшем вызывает ошибку:

while (token != NULL)
        {
            int len = strlen(token);
            b[i] = new char[300];
            b[i] = token;
            Nslov++;
            printf("%sn", b[i]);
            i++;
            bigswap(i, len, biggest);
            littleswap(i, len, little);
            token = strtok(NULL, delims);
        }

Код, при прохождении которого появляется ошибка:

for (int i = 0; i < kolslov; i++) {
    printf("n%sn", b[i]);
    delete[] b[i];
}
delete[] b;

Ошибка: вызвано срабатывание точки останова в функции delete_scalar.cpp

//
// delete_scalar.cpp
//
//      Copyright (c) Microsoft Corporation. All rights reserved.
//
// Defines the scalar operator delete.
//
#include <crtdbg.h>
#include <malloc.h>
#include <vcruntime_new.h>



void __CRTDECL operator delete(void* const block) noexcept
{
    #ifdef _DEBUG
    _free_dbg(block, _UNKNOWN_BLOCK);
    #else
    free(block);
    #endif
}

Ошибка в строке: _free_dbg(block, _UNKNOWN_BLOCK);

Цитата
Сообщение от argcargv
Посмотреть сообщение

Т.е. ты несёшь неизвестно откуда взявшуюся чушь, а другие должны бегать и искать откуда ты её берёшь?

нет никаких «т.е.»
ты сделал вывод исходя из собственных фантазий своего бреда.

а мои тезисы опираются на стандарт,
в частности, опираются на материал, доступный по ссылкам, который ты привел в #2
и самое главное: подтверждаются реальной практикой.

Цитата
Сообщение от argcargv
Посмотреть сообщение

Да, invalid pointer value не обязательно единственное значение. Их неопределённое число.

это не просто «не обязательно единственное значение» — это вообще не конкретное значение.
любое значение может стать «invalid pointer value».

одно и тоже значение: сегодня ещё валидное, а завтра уже не_валидное.

Цитата
Сообщение от argcargv
Посмотреть сообщение

Ну тупишь пока только ты, называя значение характеристикой значения.

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

Цитата
Сообщение от argcargv
Посмотреть сообщение

считаю что в C++ происходит запись в указатель только потому что я прочитал что так считают сишники.

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

но даже если принять за истину тезис, что зомби-указатели чего то там должны.
что с того?
это не даёт тебе никаких оснований считать,
что на самом деле происходит с указателями с++.

твои горячо любимые сишники нигде не писали, что в с++ по указателю происходит какая то запись.
так с какого фига ты сделал такой вывод?

эй ау, у тебя какие то проблемы с логикой?

Цитата
Сообщение от argcargv
Посмотреть сообщение

Нет такого значения, как «адрес объекта». Есть «указатель на объект».

такое впечатление, что ты деградируешь.
раньше ты настолько тупым не был.

указатель на объект — это тип данных.
его значение — адрес объекта.

я сейчас напишу фразу, которую без труда сможет понять любой,
даже начинающий программист с++:

нужно взять адрес объекта, и поместить его в указатель

теоретически: даже ты должен суметь понять.

Цитата
Сообщение от argcargv
Посмотреть сообщение

Мне вполне понятна элементарная вещь: в теме значений указателей ты плаваешь.

моя скоромная персона тебя вообще касаццо не должна.
ты со своими мозгами разберись для начала.

ты уже понял, что такое «валидный указатель» ?

Цитата
Сообщение от argcargv
Посмотреть сообщение

Еды тебе больше не будет. Можешь продолжать нести чушь сколько угодно.

обязательно расскажи про это своему психиатру.

заодно расскажи ему,
что ты таки проигнорировал объективную реальность (код #11),
ведь она противоречит твоей шизоидной теории.

Your copy constructor does a shallow copy. So, now you have two objects that both have the same recording pointer.

You should either do a deep copy, or ensure the ownership is properly transferred (by using something like std::unique_ptr<Recording> if C++11 is available.

See This question on the difference between deep and shallow copies.

Let’s look at some examples:

class ABadCopyingClass
{
public:
   ABadCopyingClass()
   {
       a_ = new int(5);
   }

   ~ABadCopyingClass()
   {
       delete a_;
   }

private:
    int* a_;   
};

The above class is bad because the default copy constructor and assignment operator will perform a shallow copy, and lead to two objects both thinking that they own the underlying a_ object. When one of them goes out of scope, the a_ will be deleted, and the other one will be left with a dangling pointer that will eventually lead to a crash.

class ABetterCopyingClass
{
public:
    ABetterCopyingClass()
       a_(new int(5))
    {
    }

    ABetterCopyingClass(const ABetterCopyingClass& r)
    {
        a_ = new int(*r.a_);
    }

    ABetterCopyingClass& operator=(const ABetterCopyingClass& r)
    {
        // in the case of reassignment...
        delete a_;

        a_ = new int(*r.a_);
        return *this;
    }

    ~ABetterCopyingClass()
    {
        delete a_;
    }

private:
    int* a_;    

};

This class improved our situation a little (note, that the normal error checking is left out in this simple example). Now the copy constructor and assignment operator properly perform the necessary deep copying. The drawback here is the amount of boilerplate code we had to add — it’s easy to get that wrong.

class ACannonicalCopyingClass
{
public:
   ACannonicalCopyingClass()
      : a_(new int(5))
   {
   }

   ACannonicalCopyingClass(ACannonicalCopyingClass&& moved_from)
   {
       a_ = std::move(moved_from.a_);
   }
private:
   std::unique_ptr<int> a_;
};

This example (C++11 only) is even better. We’ve removed a significant amount of boilerplate code, however the semantics here are a bit different. Instead of deep copying, we get in this case transfer of ownership of the underlying a_ object.

The easiest version (C++11 only) to implement is the version that provides shared ownership of the underlying a_ object. This is the version that is most similar to your provided example, with the added bonus that it does not cause a crash.

class ASharedCopyingClass
{
public:
   ASharedCopyingClass()
      : a_(std::make_shared<int>(5))
   {
   }

private:
    std::shared_ptr<int> a_;
};

This version can be copied at will, and the underlying a_ object will happily be reference counted. The last copy to go out of scope will set the reference count to 0, which will trigger the memory deallocation.

    msm.ru

    Нравится ресурс?

    Помоги проекту!

    !
    Правила раздела Visual C++ / MFC / WTL (далее Раздела)

    >
    что значит SomeClass::`scalar deleting destructor'()?

    • Подписаться на тему
    • Сообщить другу
    • Скачать/распечатать тему



    Сообщ.
    #1

    ,
    24.03.08, 10:56

      прога у меня вылетает с ошибкой:

      Цитата

      Windows has triggered a breakpoint in Magicsd.exe.

      This may be due to a corruption of the heap, and indicates a bug in Magicsd.exe or any of the DLLs it has loaded.

      The output window may have more diagnostic information

      как я понимаю, из-за двойного delete (если неправильно понимаю, прошу поправить)

      при этом в окне Call Stack встречается строка

      Цитата

      Magicsd.exe!MGuiProfileMagics::`scalar deleting destructor'() + 0x33 bytes

      причем при попытке перехода на нее говорится, что сорс-кода для нее нет и предлагает окунуться в асм.

      Что это за зверь такой?


      Cartman



      Сообщ.
      #2

      ,
      24.03.08, 20:10

        Member

        **

        Рейтинг (т): 1

        Скорее всего неправильная работа с динамической памятью — всем new должны соответствовать свои delete

        Master

        Hsilgos



        Сообщ.
        #3

        ,
        24.03.08, 21:12

          Alek86
          У тебя в классе MGuiProfileMagics деструктор, при срабатывании которого вылазит исключение


          Alek86



          Сообщ.
          #4

          ,
          25.03.08, 07:57

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


            Hryak



            Сообщ.
            #5

            ,
            25.03.08, 08:05

              Цитата Alek86 @ 25.03.08, 07:57

              то есть это обычный деструктор?

              Это не обычный деструктор (я уже писал тут, но сообщение куда-то пропало. :wacko: )
              Это код, который вызывается по delete p — в нем сначала вызывается деструктор, затем operator delete.
              Есть еще ::`vector deleting destructor’ — аналогично для delete [] p: деструкторы в цикле и operator delete []


              Alek86



              Сообщ.
              #6

              ,
              25.03.08, 09:17

                ясно, спасибо
                это и хотелось уяснить :)

                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)

                0 пользователей:

                • Предыдущая тема
                • Visual C++ / MFC / WTL
                • Следующая тема

                Рейтинг@Mail.ru

                [ Script execution time: 0,0226 ]   [ 16 queries used ]   [ Generated: 28.01.23, 18:01 GMT ]  

                Задача программы: считать из файла строку, каждое слово из которой необходимо присвоить отдельному элементу массива. Далее, найти 3 самых длинных и 3 самых коротких слова, а затем вывести все слова в порядке, обратном алфавитному. Все задачи написанная мною программа решает, но я не могу очистить память. Проблема в куске программы, в котором элементам массива b присваивается строка из переменной token (все это в цикле while). Именно после сей действия не получается воспользоваться delete[]. Все массивы уже сделал одной размерности, но все равно не помогло. В чем может быть проблема? Код прилагаю ниже. Заранее спасибо!

                #define _CRT_SECURE_NO_WARNINGS
                #include "stdafx.h"
                #include <stdlib.h>
                #include <stdbool.h>
                #include <iostream>
                #include <locale.h>
                #include <windows.h>
                #include <ctype.h>
                #include <fstream>
                #include <malloc.h>
                #include <conio.h>
                #include <vector>
                #include <algorithm>
                #include <string>
                #include <cstring>
                
                using namespace std;
                
                void bigswap(int i, int len, int biggest[]) {
                    if (len > biggest[0]) {
                        biggest[4] = biggest[2];
                        biggest[5] = biggest[3];
                        biggest[2] = biggest[0];
                        biggest[3] = biggest[1];
                        biggest[0] = len;
                        biggest[1] = i - 1;
                    }
                    else {
                        if (len > biggest[2]) {
                            biggest[4] = biggest[2];
                            biggest[5] = biggest[3];
                            biggest[2] = len;
                            biggest[3] = i - 1;
                        }
                        else {
                            if (len > biggest[4]) {
                                biggest[4] = len;
                                biggest[5] = i - 1;
                            }
                        }
                    }
                }
                void littleswap(int i, int len, int little[]) {
                    if (len < little[0]) {
                        little[4] = little[2];
                        little[5] = little[3];
                        little[2] = little[0];
                        little[3] = little[1];
                        little[0] = len;
                        little[1] = i - 1;
                    }
                    else {
                        if (len < little[2]) {
                            little[4] = little[2];
                            little[5] = little[3];
                            little[2] = len;
                            little[3] = i - 1;
                        }
                        else {
                            if (len < little[4]) {
                                little[4] = len;
                                little[5] = i - 1;
                            }
                        }
                    }
                }
                void gettext(char **b, int kolslov) {
                    printf("Слова, выведенные в порядке, обратном алфавитному:nn");
                    for (int i = 0; i < kolslov; i++) {
                        printf("%sn", b[i]);
                    }
                    printf("nn");
                }
                void minusswap(char **b, int kolslov) {
                    for (int i = 0; i < (kolslov - 1); i++) {
                        for (int j = i + 1; j < kolslov; j++) {
                            if ((int)b[i][0] < 91) {
                                b[i][0] = (char)((int)b[i][0] + 32);
                            }
                            if ((int)b[j][0] < 91) {
                                b[j][0] = (char)((int)b[j][0] + 32);
                            }
                            if (strcmp(b[i], b[j]) < 0) swap(b[i], b[j]);
                        }
                    }
                }
                void initialization(int biggest[], int little[]) {
                    for (int i = 0; i < 6; i++) {
                        biggest[i] = -1;
                        little[i] = 100;
                    }
                }
                
                
                int main() {
                
                    char **b, *buffer, *token, delims[] = " n.,!?/<>|)(*:;"";
                    const int len_text = 300;
                    int max_len = 0, size_len = 0, Nslov = 0, kolslov = 0, menu = 0;
                    int biggest[6], little[6];
                    FILE *load = NULL;
                
                    setlocale(LC_ALL, "Russian");
                    SetConsoleCP(1251);
                    SetConsoleOutputCP(1251);
                
                    printf("Данная программа считывает ваш текст из файла, находит в нем три самых длинных и три самых коротких слова, а также располагает все слова в порядке, обратном алфавитному.nnn");
                    system("pause");
                    system("cls");
                
                    for (;;) {
                
                        load = fopen("FILE.txt", "r");
                        fscanf_s(load, "%in", &kolslov);
                        initialization(biggest, little);
                
                        b = new char*[kolslov];
                        /*for (int i = 0; i < kolslov; i++) {
                            b[i] = new char[30];
                        }*/
                
                        buffer = new char[300];
                        token = new char[300];
                
                        fgets(buffer, len_text, load);
                        printf("Первоначальный текст:nn%snnnНайденные слова:nn", buffer);
                
                        token = strtok(buffer, delims);
                
                        int i = 0;
                
                        while (token != NULL)
                        {
                            int len = strlen(token);
                            b[i] = new char[300];
                            b[i] = token;
                            Nslov++;
                            printf("%sn", b[i]);
                            i++;
                            bigswap(i, len, biggest);
                            littleswap(i, len, little);
                            token = strtok(NULL, delims);
                        }
                
                        printf("nnТри самых длинных слова в данном тексте:nn%sn%sn%snn", b[biggest[1]], b[biggest[3]], b[biggest[5]]);
                        printf("nТри самых коротких слова в данном тексте:nn%sn%sn%snnn", b[little[1]], b[little[3]], b[little[5]]);
                
                        minusswap(b, kolslov);
                        gettext(b, kolslov);
                
                        system("pause");
                
                        for (int i = 0; i < kolslov; i++) {
                            printf("n%sn", b[i]);
                            delete[] b[i];
                        }
                        delete[] b;
                
                        fclose(load);
                        system("pause");
                        system("cls");
                    }
                    system("pause");
                }
                

                Код того места, где появляется проблема, которая в дальнейшем вызывает ошибку:

                while (token != NULL)
                        {
                            int len = strlen(token);
                            b[i] = new char[300];
                            b[i] = token;
                            Nslov++;
                            printf("%sn", b[i]);
                            i++;
                            bigswap(i, len, biggest);
                            littleswap(i, len, little);
                            token = strtok(NULL, delims);
                        }
                

                Код, при прохождении которого появляется ошибка:

                for (int i = 0; i < kolslov; i++) {
                    printf("n%sn", b[i]);
                    delete[] b[i];
                }
                delete[] b;
                

                Ошибка: вызвано срабатывание точки останова в функции delete_scalar.cpp

                //
                // delete_scalar.cpp
                //
                //      Copyright (c) Microsoft Corporation. All rights reserved.
                //
                // Defines the scalar operator delete.
                //
                #include <crtdbg.h>
                #include <malloc.h>
                #include <vcruntime_new.h>
                
                
                
                void __CRTDECL operator delete(void* const block) noexcept
                {
                    #ifdef _DEBUG
                    _free_dbg(block, _UNKNOWN_BLOCK);
                    #else
                    free(block);
                    #endif
                }
                

                Ошибка в строке: _free_dbg(block, _UNKNOWN_BLOCK);

                Я изучил C ++ в онлайн-курсе, но у меня возникла проблема с оператором «delete» в Visual Studio. Когда удаление выполняется, он открывает файл delete_scalar.cpp и показывает:

                ConsoleApplication.exe вызвал точку останова. исключение

                Я уже перемещаю папку SymbolCache из temp, включая wntdll.pdb и т. Д.

                #include "pch.h"#include <iostream>
                using namespace std;
                
                int main()
                {
                int *pInt = new int;
                *pInt = 3;
                cout << *pInt << endl;
                cout << pInt << endl;
                
                delete[] pInt; //error -- UPDATED: still get error with `delete pInt;`
                
                return 0;
                }
                

                здесь информация о выходе,

                «ConsoleApplication11.exe» (Win32): загружен «C: Windows SysWOW64 ntdll.dll». Символы загружены.
                «ConsoleApplication11.exe» (Win32): загружен «C: Windows SysWOW64 kernel32.dll». Символы загружены.
                «ConsoleApplication11.exe» (Win32): загружен «C: Windows SysWOW64 KernelBase.dll». Символы загружены.
                «ConsoleApplication11.exe» (Win32): загружен «C: Windows SysWOW64 msvcp140d.dll». Символы загружены.
                «ConsoleApplication11.exe» (Win32): загружен «C: Windows SysWOW64 vcruntime140d.dll». Символы загружены.
                «ConsoleApplication11.exe» (Win32): загружен «C: Windows SysWOW64 ucrtbased.dll». Символы загружены.
                Поток 0x2fd0 вышел с кодом 0 (0x0).
                HEAP [ConsoleApplication11.exe]: неверный адрес, указанный для RtlValidateHeap (00930000, 009359E8)
                ConsoleApplication11.exe вызвал точку останова.

                delete_scalar.cpp из самого визуала,

                //
                // delete_scalar.cpp
                //
                //      Copyright (c) Microsoft Corporation. All rights reserved.
                //
                // Defines the scalar operator delete.
                //
                #include <crtdbg.h>
                #include <malloc.h>
                #include <vcruntime_new.h>
                #include <vcstartup_internal.h>
                
                _CRT_SECURITYCRITICAL_ATTRIBUTE
                void __CRTDECL operator delete(void* const block) noexcept
                {
                #ifdef _DEBUG
                _free_dbg(block, _UNKNOWN_BLOCK); // the circle X symbol showed up there
                #else
                free(block);
                #endif
                }
                

                Я уже делаю точки останова, такие как включение и удаление, но точка останова все еще срабатывает на delete_scalar.cpp с отображением символа X круга.

                0

                Решение

                Если вы попросите памяти с newнеобходимо удалить с помощью delete,

                Использовать только delete [ ] когда ты использовал new [ ], Несовпадение двух приводит к неопределенному поведению.

                2

                Другие решения

                Других решений пока нет …

                Я изучил C++ на онлайн-курсе, но у меня проблема с оператором delete в Visual Studio. Когда выполняется удаление, он открывает файл delete_scalar.cpp и показывает:

                ConsoleApplication.exe has triggered a breakpoint. exception thrown

                Я уже перемещаю папку SymbolCache из temp, включая wntdll.pdb и т. д.

                #include "pch.h"
                #include <iostream>
                using namespace std;
                
                int main()
                {
                int *pInt = new int;
                *pInt = 3;
                cout << *pInt << endl;
                cout << pInt << endl;
                
                delete[] pInt; //error -- UPDATED: still get error with `delete pInt;` 
                
                return 0;
                }
                

                Здесь выходная информация,

                ‘ConsoleApplication11.exe’ (Win32): Loaded ‘C:WindowsSysWOW64ntdll.dll’. Symbols loaded.
                ‘ConsoleApplication11.exe’ (Win32): Loaded ‘C:WindowsSysWOW64kernel32.dll’. Symbols loaded.
                ‘ConsoleApplication11.exe’ (Win32): Loaded ‘C:WindowsSysWOW64KernelBase.dll’. Symbols loaded.
                ‘ConsoleApplication11.exe’ (Win32): Loaded ‘C:WindowsSysWOW64msvcp140d.dll’. Symbols loaded.
                ‘ConsoleApplication11.exe’ (Win32): Loaded ‘C:WindowsSysWOW64vcruntime140d.dll’. Symbols loaded.
                ‘ConsoleApplication11.exe’ (Win32): Loaded ‘C:WindowsSysWOW64ucrtbased.dll’. Symbols loaded.
                The thread 0x2fd0 has exited with code 0 (0x0).
                HEAP[ConsoleApplication11.exe]: Invalid address specified to RtlValidateHeap( 00930000, 009359E8 )
                ConsoleApplication11.exe has triggered a breakpoint.

                Delete_scalar.cpp из самого визуала,

                //
                // delete_scalar.cpp
                //
                //      Copyright (c) Microsoft Corporation. All rights reserved.
                //
                // Defines the scalar operator delete.
                //
                #include <crtdbg.h>
                #include <malloc.h>
                #include <vcruntime_new.h>
                #include <vcstartup_internal.h>
                
                _CRT_SECURITYCRITICAL_ATTRIBUTE
                void __CRTDECL operator delete(void* const block) noexcept
                {
                #ifdef _DEBUG
                _free_dbg(block, _UNKNOWN_BLOCK); // the circle X symbol showed up there
                #else
                free(block);
                #endif
                }
                

                Я уже выполняю такие действия с точкой останова, как включение и удаление, но точка останова все еще срабатывает на delete_scalar.cpp с отображением символа X в виде круга.

                • Remove From My Forums
                • Question

                • Greetings…

                  Anyone can advise what is wrong and what can be done?

                  	CRunProcess* m_Proc[NUM_PROC];
                  	
                  	CMainClass::~CMainClass()
                  	{
                  		for (int i = 0; i < NUM_PROC; i++)
                  		{
                  			if (m_Proc[i] != NULL)
                  			{
                  				delete m_Proc[i];
                  				m_Proc[i] = NULL;
                  			}
                  		}
                  	}	
                  	
                  	
                  
                  	m_Proc[RUN_PROCESS_1] = new CProcess1();
                  	virtual ~CProcess1()
                  	{
                  		// OK
                  	}
                  	
                  	m_Proc[RUN_PROCESS_2] = new CProcess2();
                  	virtual ~CProcess2()
                  	{
                  		// OK
                  	}
                  	
                  	m_Proc[RUN_PROCESS_3] = new CProcess3();
                  	virtual ~CProcess3()
                  	{
                  	    // Here Have Nothing also encountered error during Program exit 
                  		// NOT OK ; calling destructor Twice, failed on 2nd time
                  		// An unhandled exception was encountered during a user callback
                  		// Scalar deleting destructor
                  	}
                  	
                  	m_Proc[RUN_PROCESS_4] = new CProcess4();
                  	virtual ~CProcess4()
                  	{
                  		// OK
                  	}

                  Thanks a bunch!

                  CHeers~~~

                • Forum
                • General C++ Programming
                • Execption thrown when deleting a valid p

                Execption thrown when deleting a valid pointer

                Hi Fellow Programmers!

                I am having some trouble with this small project.

                I am getting a exception thrown at me from «delete_scalar.cpp:Line 34: _free_dbg(block, _UNKNOWN_BLOCK);»

                Which stems from me trying to delete a pointer holding a char array.

                Here is context

                The Destructor

                1
                2
                3
                4
                5
                6
                7
                8
                9
                10
                11
                12
                13
                14
                15
                16
                17
                18
                19
                20
                21
                22
                23
                	Menu::~Menu() {
                		//Deallocate title
                		if (m_title) {
                			delete[] m_title;
                		}
                		m_title = nullptr;
                
                		//Deallocate menu items
                		if (m_menuCount > 0) {
                			for (int i = 0; i < m_menuCount; i++) {
                				delete m_menuItem[i];
                				m_menuItem[i] = nullptr;
                			}
                		}
                
                
                		//Reset values
                		m_menuCount = 0;
                		m_indentation = 0;
                
                		m_safe = true;
                
                	}

                Here is the declarations of the objects

                1
                2
                3
                4
                5
                   Menu mainMenu("** Main Menu **");
                   Menu subMenu1("** Sub Menu One **", 1);
                   Menu subMenu2("** Sub Menu **", 2);
                   Menu tempMenu("** Temp **");
                   Menu invMenu("** To test Invalid Menu **");

                When the client code completes and the destructors start deleting the pointers, once the destructor hits mainMenu it throws the exception, the first four objects exit fine.

                Here is the values right at return 0, before destructors get called.

                1
                2
                3
                4
                5
                6
                7
                8
                9
                10
                11
                12
                13
                14
                15
                16
                17
                18
                19
                20
                21
                22
                23
                24
                25
                26
                27
                28
                29
                30
                31
                -		invMenu	{m_title=0x00925288 "" m_menuItem=0x0073fd20 {0x00000000 <NULL>, 0x00000000 <NULL>, 0x00000000 <NULL>, ...} ...}	sdds::Menu
                +		m_title	0x00925288 ""	char *
                +		m_menuItem	0x0073fd20 {0x00000000 <NULL>, 0x00000000 <NULL>, 0x00000000 <NULL>, 0x00000000 <NULL>, 0x00000000 <NULL>, ...}	sdds::MenuItem *[11]
                		m_menuCount	0	int
                		m_indentation	0	int
                		m_safe	true	bool
                -		mainMenu	{m_title=0x00929b80 "" m_menuItem=0x0073fe30 {0x00931cd0 {m_item=0xdddddddd <Error reading characters of string.> }, ...} ...}	sdds::Menu
                +		m_title	0x00929b80 ""	char *
                +		m_menuItem	0x0073fe30 {0x00931cd0 {m_item=0xdddddddd <Error reading characters of string.> }, 0x00931f40 {m_item=...}, ...}	sdds::MenuItem *[11]
                		m_menuCount	0	int
                		m_indentation	0	int
                		m_safe	true	bool
                -		subMenu1	{m_title=0x00931f70 "" m_menuItem=0x0073fdec {0x00931df0 {m_item=0xdddddddd <Error reading characters of string.> }, ...} ...}	sdds::Menu
                +		m_title	0x00931f70 ""	char *
                +		m_menuItem	0x0073fdec {0x00931df0 {m_item=0xdddddddd <Error reading characters of string.> }, 0x00931e80 {m_item=...}, ...}	sdds::MenuItem *[11]
                		m_menuCount	0	int
                		m_indentation	0	int
                		m_safe	true	bool
                -		subMenu2	{m_title=0x00925248 "** Sub Menu **" m_menuItem=0x0073fda8 {0x00931d90 {m_item=0x0092e1d0 "The first" }, ...} ...}	sdds::Menu
                +		m_title	0x00925248 "** Sub Menu **"	char *
                +		m_menuItem	0x0073fda8 {0x00931d90 {m_item=0x0092e1d0 "The first" }, 0x00931fd0 {m_item=0x0092e320 "The second" }, ...}	sdds::MenuItem *[11]
                		m_menuCount	3	int
                		m_indentation	2	int
                		m_safe	false	bool
                -		tempMenu	{m_title=0x00933278 "** Sub Menu **" m_menuItem=0x0073fd64 {0x00931c40 {m_item=0x0092e208 "The first" }, ...} ...}	sdds::Menu
                +		m_title	0x00933278 "** Sub Menu **"	char *
                +		m_menuItem	0x0073fd64 {0x00931c40 {m_item=0x0092e208 "The first" }, 0x00931dc0 {m_item=0x0092e2b0 "The second" }, ...}	sdds::MenuItem *[11]
                		m_menuCount	3	int
                		m_indentation	2	int
                		m_safe	false	bool
                

                It’s confusing me, weird error aswell oh and heres the error as seen from my eyes.

                
                Debug Assertion Failed!
                
                Program:
                ....myFilesProject.exe
                File:minkernelcrtsucrtsrcappcrtheapdebug_heap.cpp
                Line: 904
                
                Expression: _CrtIsValidHeapPointer(block)
                

                P.S does memory management in c++ ever become second nature to you oldies asking from a starter in college

                Last edited on

                Good luck finding a programmer who can correct a memory problem without reading the source code.

                There’s no evidence of any exception being thrown in what you posted.
                Post a small, self-contained, compilable example of the problem:
                http://www.sscce.org/

                P.S does memory management in c++ ever become second nature to you oldies asking from a starter in college

                It becomes natural when you stop writing

                new

                everywhere.

                Last edited on

                Show how you construct the objects. Show the places you call new and new[].

                Also, setting a pointer to null in a destructor is probably useless because the object the pointer belongs to is about to not exist anyway.
                Also also, your check on line 9 is redundant.
                So is your check on line 3.

                P.S does memory management in c++ ever become second nature to you oldies asking from a starter in college

                If you don’t use new & delete, you don’t need to worry about «classic» memory management, although should always be conscious of what is happening in your code.

                Last edited on

                Here is the reproducable example, tried to keep it simple.

                1
                2
                3
                4
                5
                6
                7
                8
                9
                10
                11
                12
                13
                14
                15
                16
                17
                18
                19
                20
                21
                22
                23
                24
                25
                26
                27
                28
                29
                30
                31
                32
                33
                34
                35
                36
                37
                38
                39
                40
                41
                42
                43
                44
                45
                46
                47
                48
                49
                50
                
                #define _CRT_SECURE_NO_WARNINGS
                
                #include <cstring>
                #include <iostream>
                
                class tempMenu {
                private:
                	char* m_title;
                public:
                	tempMenu(const char* title) {
                		//Check title, allocate size for array, copy into array
                		if (title && title[0] != '') {
                			m_title = new char[strlen(title) + 1];
                			strcpy(m_title, title);
                		}
                		else {	//else set to nullptr
                			m_title = nullptr;
                		}
                	}
                
                	~tempMenu() {
                		//Deallocate, this is where it breaks
                		delete[] m_title;
                	}
                
                	void display() {
                		std::cout << m_title << std::endl;
                	}
                };
                
                
                //Display menu
                void testMenu(tempMenu temp) {
                	temp.display();
                }
                
                int main(){
                	
                	//Create object
                	tempMenu obj("Object");
                
                	//Gets passed into new scope
                	testMenu(obj);
                
                	//Returns from scope after going throught destructor, object is essentialy destroyed here
                
                	return 0;	//calls obj destructor, triggers error at delete [] m_title in destructor
                
                }

                I have to keep it passed by value.

                Here is the client code with values before and after being passed into the new scope

                 
                   testMenus(mainMenu, subMenu1, subMenu2);
                 
                   void testMenus(Menu m, Menu sub1, const Menu& sub2)

                Here are the values before going in…

                1
                2
                3
                4
                5
                6
                7
                8
                9
                10
                -		mainMenu	{m_title=0x01591068 "** Main Menu **" m_menuItem=0x012ff794 {0x015924e8 {m_item=0x0158e0f0 "Option one" }, ...} ...}	sdds::Menu
                -		m_title	0x01591068 "** Main Menu **"	char *
                			42 '*'	char
                -		subMenu1	{m_title=0x01590ca8 "** Sub Menu One **" m_menuItem=0x012ff750 {0x01592488 {m_item=0x01590f28 "Selection one" }, ...} ...}	sdds::Menu
                -		m_title	0x01590ca8 "** Sub Menu One **"	char *
                			42 '*'	char
                -		subMenu2	{m_title=0x01590ea8 "** Sub Menu **" m_menuItem=0x012ff70c {0x01592638 {m_item=0x0158e1d0 "The first" }, ...} ...}	sdds::Menu
                -		m_title	0x01590ea8 "** Sub Menu **"	char *
                			42 '*'	char
                

                and after leaving scope back to client code….

                1
                2
                3
                4
                5
                6
                7
                -		mainMenu	{m_title=0x01591068 "ÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝ" m_menuItem=0x012ff794 {0x015924e8 {m_item=0xdddddddd <Error reading characters of string.> }, ...} ...}	sdds::Menu
                +		m_title	0x01591068 "ÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝ"	char *
                -		subMenu1	{m_title=0x01590ca8 "ÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝ" m_menuItem=0x012ff750 {0x01592488 {m_item=0xdddddddd <Error reading characters of string.> }, ...} ...}	sdds::Menu
                +		m_title	0x01590ca8 "ÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝ"	char *
                -		subMenu2	{m_title=0x01590ea8 "** Sub Menu **" m_menuItem=0x012ff70c {0x01592638 {m_item=0x0158e1d0 "The first" }, ...} ...}	sdds::Menu
                +		m_title	0x01590ea8 "** Sub Menu **"	char *
                

                mainMenu and subMenu1 both get deleted, but mainMenu is the one that crashes when being destructed, subMenu1 destructs before mainMenu…

                Let’s reduce the problem more:

                1
                2
                3
                4
                5
                6
                7
                8
                9
                10
                11
                struct a
                { 
                  int* ptr_ = nullptr;
                  ~a() { delete ptr_; }
                };
                
                int main()
                {
                  a x { new int };
                  a y = x;
                }

                See:
                http://coliru.stacked-crooked.com/a/b06d48900f33a4bd

                After line 10, both

                x.ptr_

                and

                y.ptr_

                point to the same object.

                Destruction occurs in reverse order of construction. When

                main

                returns,

                y.~a

                is called, deleting

                y.ptr_

                . Next,

                x.~a

                is called, deleting

                x.ptr_

                . Unfortunately,

                x.ptr_

                and

                y.ptr_

                have the same value. The source of the problem is the attempt to

                delete

                the same pointer twice.

                In the above program, we copy x into y on line 10, and this is the source of the problem. The copy in your code is harder to spot, but it occurs on line 44.

                To fix the problem, either
                a.) disallow copies; or
                b.) duplicate the resource.

                Case a.) is the simplest option, but it isn’t always suitable. We add the definitions

                1
                2
                3
                4
                5
                6
                7
                8
                9
                10
                11
                12
                class tempMenu 
                {
                public:
                  // disallow initialization of one tempMenu from another
                  tempMenu(tempMenu const&) = delete; 
                  // disallow initialization of one tempMenu from a "temporary" tempMenu
                  tempMenu(tempMenu &&) = delete;
                  // disallow assignment of this tempMenu from another
                  tempMenu& operator=(tempMenu const&) = delete;
                  // disallow assignment of this tempMenu from a "temporary" tempMenu
                  tempMenu& operator=(tempMenu &&) = delete;
                };

                to our code. Now we are forbidden to copy or assign tempMenu objects; attempts to do so will result in a compiler error, and not an error that results in wrong behavior on the user’s machine.

                We can still pass tempMenu objects as function arguments by binding them to reference parameters:

                1
                2
                3
                4
                void testMenu(tempMenu /*const*/& temp) 
                {
                	temp.display();
                }

                Last edited on

                How do we duplicate the resource, my module uses the functionality of

                 
                Menu& operator=(const Menu& menu);

                to assign menu’s to one another

                Add the definitions

                1
                2
                3
                4
                5
                6
                7
                8
                9
                10
                11
                12
                13
                14
                15
                16
                17
                tempMenu(tempMenu const& other)
                  : m_title(new char[strlen(other.m_title) + 1]) 
                {
                  strcpy(m_title, other.m_title);    
                }
                
                tempMenu& operator=(tempMenu rhs) 
                {
                  swap(rhs);
                  return *this;
                }
                
                void swap(tempMenu& that) noexcept
                {
                  using std::swap;
                  swap(this->m_title, that.m_title);
                }

                to

                tempMenu

                Look up the «copy-and-swap» idiom for more information about the copy assignment operator. The copy constructor is the more problematic of the two, but it should do for now.

                Last edited on

                Topic archived. No new replies allowed.

                Я изучил C ++ на онлайн-курсе, но у меня проблема с оператором delete в Visual Studio. При выполнении удаления открывается файл delete_scalar.cpp и отображается:

                ConsoleApplication.exe вызвал точку останова. выброшенное исключение

                Я уже перемещаю папку SymbolCache из temp, включая wntdll.pdb и т. Д.

                #include "pch.h"
                #include <iostream>
                using namespace std;
                
                int main()
                {
                int *pInt = new int;
                *pInt = 3;
                cout << *pInt << endl;
                cout << pInt << endl;
                
                delete[] pInt; //error -- UPDATED: still get error with `delete pInt;` 
                
                return 0;
                }
                

                Здесь выходная информация,

                ‘ConsoleApplication11.exe’ (Win32): загружен ‘C: Windows SysWOW64 ntdll.dll’. Символы загружены. ‘ConsoleApplication11.exe’ (Win32): загружен ‘C: Windows SysWOW64 kernel32.dll’. Символы загружены. ‘ConsoleApplication11.exe’ (Win32): загружен ‘C: Windows SysWOW64 KernelBase.dll’. Символы загружены. «ConsoleApplication11.exe» (Win32): загружен «C: Windows SysWOW64 msvcp140d.dll». Символы загружены. «ConsoleApplication11.exe» (Win32): загружен «C: Windows SysWOW64 vcruntime140d.dll». Символы загружены. «ConsoleApplication11.exe» (Win32): загружен «C: Windows SysWOW64 ucrtbased.dll». Символы загружены. Поток 0x2fd0 завершился с кодом 0 (0x0). HEAP [ConsoleApplication11.exe]: для RtlValidateHeap (00930000, 009359E8) указан недопустимый адрес. Программа ConsoleApplication11.exe вызвала точку останова.

                Delete_scalar.cpp из самого визуала,

                //
                // delete_scalar.cpp
                //
                //      Copyright (c) Microsoft Corporation. All rights reserved.
                //
                // Defines the scalar operator delete.
                //
                #include <crtdbg.h>
                #include <malloc.h>
                #include <vcruntime_new.h>
                #include <vcstartup_internal.h>
                
                _CRT_SECURITYCRITICAL_ATTRIBUTE
                void __CRTDECL operator delete(void* const block) noexcept
                {
                    #ifdef _DEBUG
                    _free_dbg(block, _UNKNOWN_BLOCK); // the circle X symbol showed up there
                    #else
                    free(block);
                    #endif
                }
                

                Я уже использую точки останова, такие как включение и удаление, но точка останова все еще срабатывает на delete_scalar.cpp с отображением символа X в виде круга.

                1 ответ

                Лучший ответ

                Если вы запрашиваете память с помощью new, вам необходимо удалить ее с помощью delete.

                Используйте delete [ ] только тогда, когда вы использовали new [ ]. Несоответствие этих двух параметров ведет к неопределенному поведению.


                4

                Aganju
                30 Окт 2018 в 07:50

                • Forum
                • General C++ Programming
                • Debugging a delete error?

                Debugging a delete error?

                I am pretty sure I have some sort of deletion error. How would I go about debugging it? I am still not savvy with using the call stack and finding out what it can tell me. My program runs fine (or the output is correct) but at the very end it still puts out an error from a delete_scalar.cpp file.

                «A breakpoint instruction (__debugbreak() statement or a similar call) was executed in Project x.exe.»
                I don’t know if I want to post my whole code, but I did use Dr. memory and it said I had 0 leaks. Most likely the last delete function is causing the error.

                **a friend had me add a message when the destructor happens, and I test for it once but it’s printing out 3 times.

                Last edited on

                The delete error is most likely that you are trying to free memory more than once. This happens when a shallow (vs. deep) copy is performed, i.e. when the pointer instead of the whole data is copied.

                This can be prevented by using smart pointer (std::shared_ptr or std::unique_ptr) or a container. Depends on your needs. You should avoid using raw pointer when possible.

                Assuming the struct/class uses dynamic memory, have you defined a correct copy constructor and an assignment operator (operator=)? If you haven’t then the default ones supplied are not appropriate as they do a shallow copy rather than the required deep copy.

                As you haven’t provided the code, we can’t say much else without seeing it as this could be caused in several ways depending upon which the code is trying to do. With C++, just because the code gives a semblance of working this doesn’t mean it’s working correctly.

                while it won’t fix errors in your code, if you set pointers to nullptr every time you delete them and every time you initialize one (unless you init to a valid pointer) you will have safe code, even if you blunder and delete twice, because deletion of nullptr does nothing & is safe, you just waste some time doing nothing there.

                Its best if you figure this out so its not called more than once, and understand how to make that work, but its also best if you do the above, just for safer, more goof-proofed code.

                ** this won’t fix your issue if the issue is that you copied the pointer to another and deleted both.

                Last edited on

                It is a possibility that you have overwritten some block of memory snd corrupted the heap. If that is the case, it might show up when delete is called.

                Last edited on

                @jonnin yes I had realized I might need to add some nullptrs in my code, and i probably will run into the second thing you mentioned since this is a bit complicated a nullptr might not fix it. So I will try and post some code soon.

                Ok I am still getting 3 destructor errors, I probably got bad advice from one of my tutors since I got help with the big 3.

                I think for this I will keep smart pointers out, and probably encouraged not to use that right now.

                1
                2
                3
                4
                5
                6
                7
                8
                9
                10
                11
                12
                13
                14
                15
                16
                17
                18
                19
                20
                21
                22
                23
                24
                25
                void binarytree::operator=(const binarytree& source)
                {
                	if (this != &source)
                	{
                		clear(root);
                		if(source.root != nullptr)
                		copy(source.root, root);
                	}
                
                }
                
                void binarytree::copy(treenode* dest, treenode*& source)
                {
                	if (source == nullptr)
                	{
                		dest = nullptr;
                	}
                	else
                	{
                		source->data = dest->data;
                		source = new treenode;
                		copy(source->left, dest->left);
                		copy(source->right, dest->right);
                	}
                }

                My headers are:

                1
                2
                3
                4
                static void copy(treenode* destroot, treenode*& source);
                
                //public
                void operator=(const binarytree& root);

                here’s my destructor:

                1
                2
                3
                4
                5
                6
                7
                8
                9
                10
                11
                12
                13
                14
                15
                //header
                ~binarytree();
                
                //cpp
                binarytree::~binarytree()
                {
                	clear(root);
                	cout << "Destructor executed" << endl;
                }
                //main 
                	//Testing the destructor
                	binarytree test1;
                
                
                	test1.~binarytree();

                Oh shoot I think I see my error, some code has the destructor as a virtual. The other part is i am passing in clear(root). Normally I just call clear() inside the destructor, so ya it keeps deleting itself I think. My other issue is I had «source = new treenode;» after actually copying the data over, can’t do that.

                Ok so I think because I have a struct of treenode in my private that is inside my binary tree class I apparently have to make the destructor virtual?

                Last edited on

                do you understand the diff between = and == ?
                look closely.

                @jonnin I re-edited it, take a look. It’s my damn laptop it likes to multi input sometimes.

                Last edited on

                Sleep tight guys I figured it out. I also had 2 objects in main that were created so it was normal to have multiple destructions.

                Topic archived. No new replies allowed.

              • Deh 80prs ошибка 10 pioneer
              • Deh 1600ubg ошибка усилителя
              • Degen 1103 работа над ошибками
              • Defrfail ошибка кариер что это
              • Defrfail ошибка кариер что делать