Russian Qt Forum
Ноябрь 22, 2024, 12:16 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: есть в С++ стандартная функция проверки валидности указателя?  (Прочитано 11061 раз)
artur567297@gmail.com
Новичок

Offline Offline

Сообщений: 7


Просмотр профиля
« : Июнь 27, 2022, 01:00 »

Здравствуйте. Помогите новичку с проверкой указателя перед удалением.
Недавно начал заниматься с++ и такая проблема:
Создал простой класс он содержит указатель char* buffer, конструктор и деструктор, и больше не чего вот его код: 
class MyStringDefaultCopy
{
 
private:
    char* buffer;
MyStringDefaultCopy(const char* initString) // Constructor
    {
       buffer = new char[strlen(initString) + 1];
       strcpy(buffer, initString); 
    }

~MyStringDefaultCopy() // Destructor
    {
        delete[] buffer;
        *buffer = NULL;     
    }
}
Создал одну простую функцию:
void UseMyString(MyStringDefaultCopy str)
{
    cout << "вызов функции UseMyString  " << endl;
}
Код Main простой состоит из двух строк:
MyStringDefaultCopy sayHello("Hello");
UseMyString(sayHello);
ПРОБЛЕМА: Код Main отрабатывает но по завершении программы выдает ошибку _CrtIsValidHeapPointer. Я знаю из за чего возникает эта ошибка: проблема вот в чем в коде Main при вызове функции UseMyString передается копия объекта sayHello, которая соответственно в конце функции уничтожается. Так как у объекта sayHello есть указатель и деструктор но нет копирующего конструктора, по этому при создании копии для функции UseMyString используется копирующий конструктор по умолчанию который просто скопирует все указатели в классе, соответственно после выполнения функции UseMyString удаляется копия MyStringDefaultCopy str и вызывается деструктор который делает указатель buffer неопределенным. При окончании Main удаляется уже основной объект sayHello и вызывается его деструктор который указатель buffer уже удалить не может так как он не определен. Собственно вопрос есть метод проверки валидности указателя перед его удалением: типа *buffer = NULL – не помогает. Можно присвоить после удаления указателю значение, например *buffer = “удален” и перед удалением сравнивать на это значение но может есть стандартная функция проверки валидности указателя?   
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #1 : Июнь 27, 2022, 10:21 »

Цитировать
Я знаю из за чего возникает эта ошибка
все верно

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

голыми указателями для управления памятью вообще пользоваться очень не рекомендуется чтобы избежать огромного слоя ошибок, для этого давно придумали «умные» указатели (std::unique_ptr, std::shared_ptr).

кстати, выражение *buffer = NULL; в данном случае ошибочное, т.к. разыменовывается «мусорный» указатель.

P.S. для оформления кода есть специальный тэг: [ code=cpp]код [ /code] (только пробелы после [ убрать)
« Последнее редактирование: Июнь 27, 2022, 10:24 от kambala » Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
artur567297@gmail.com
Новичок

Offline Offline

Сообщений: 7


Просмотр профиля
« Ответ #2 : Июнь 27, 2022, 14:34 »

спасибо
Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 872


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #3 : Июнь 27, 2022, 15:07 »

Собственно вопрос есть метод проверки валидности указателя перед его удалением: типа *buffer = NULL – не помогает. Можно присвоить после удаления указателю значение, например *buffer = “удален” и перед удалением сравнивать на это значение но может есть стандартная функция проверки валидности указателя?   
Вы путаете указатель и область памяти, на который этот указатель "указывает", что вам уже и подсказали. Можно buffer = nullptr, но это не решает вашу, надо отметить, надуманную проблему. Используйте конструктор копирования, в котором для копии распределяется своя память и переносится содержимое из копируемого объекта.
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
juvf
Программист
*****
Offline Offline

Сообщений: 570


Просмотр профиля
« Ответ #4 : Январь 23, 2023, 10:33 »

Собственно вопрос есть метод проверки валидности указателя перед его удалением: типа *buffer = NULL – не помогает. Можно присвоить после удаления указателю значение, например *buffer = “удален” и перед удалением сравнивать на это значение но может есть стандартная функция проверки валидности указателя?   

Код:
~MyStringDefaultCopy() // Destructor
    {
        delete[] buffer;
        buffer = 0; //или buffer  = NULL; без разименования *buffer = NULL
    }
вызов деструктора по нулевому указателю разрешенная в с++ операция. "delete 0;" - операция ни чего не делает и безопасная.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.112 секунд. Запросов: 23.