Форум программистов, компьютерный форум CyberForum.ru

Указатель при инициализации не равен NULL - C++

Восстановить пароль Регистрация
 
TempuSFatumA
 Аватар для TempuSFatumA
1 / 1 / 0
Регистрация: 02.04.2013
Сообщений: 87
13.04.2013, 21:36     Указатель при инициализации не равен NULL #1
Здравия желаю!

C++
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
myClass myClass::operator=(myClass iniOb)
{
    char *temp; //Указатель на копию массива из объекта iniOb
 
    //Выделение памяти под копируемый массив
    try{tempNum = new char[iniOb.Len];}
    catch(std::bad_alloc){throw;}
 
    //Заполнение массива
    for(unsigned int i=0; i<iniOb.Len; i++)temp[i]=iniOb.Ptr[i];
 
    if(Ptr)//И вот здесь ошибка
    {
        //Освобождение памяти из-под старого массива объекта, стоящего слева от =
        delete []Ptr;
    }
 
    //Указателю-переменной из левого объекта присваивается адрес копии массива
    Ptr=temp;
    //длине массива левого объекта присваивается длина массива правого
    Len=iniOb.Len;
    return *this;
}
 
int main()
{
    myClass a("-12");
    myClass b=a;
    return 0;
}
При инициализации b указатель принимает ненулевое значение(при отладке пишет temp=0xcccccccc, а не NULL(0x00000000)). Программа видя не нуль вызывает delete []Ptr;. Вылетает
Необработанное исключение по адресу 0x637B7508 (msvcr110d.dll) в ConsoleApplication7.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0xCCCCCCC0.
Убрать delete нельзя, ибо возвращение памяти необходимо при присваивании уже инициализированному объекту.
Что с этим сделать можно?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
yekka
384 / 148 / 8
Регистрация: 12.05.2011
Сообщений: 450
13.04.2013, 21:44     Указатель при инициализации не равен NULL #2
Какой кошмар!

Во-первых, оператор присваивания должен выглядеть совсем не так, а как-то так:
C++
1
2
3
4
5
6
7
SimpleCircle & SimpleCircle::operator=(const SimpleCircle & rhs)
{
    if(this == &rhs)
       return *this;
    itsRadius = rhs.getRadius();
    return *this;
}
а во-вторых, в приведенном коде не будет вызываться оператор присваивания. здесь будет вызываться конструктор копирования и его нужно также явно написать.
TempuSFatumA
 Аватар для TempuSFatumA
1 / 1 / 0
Регистрация: 02.04.2013
Сообщений: 87
13.04.2013, 22:42  [ТС]     Указатель при инициализации не равен NULL #3
Я дал не полную инфу. Конструктор копирования вызывается при возвращении значения из функции преобразования, которая возвращает временный объект. А после идет вызов оператора = , который приводит к исключению.
C++
1
2
3
4
5
6
myClass charToNum(const char* const a);
 
myClass(const char* const a)
{
      *this=charToNum(a);
}
Сам оператор я изменил на
C++
1
myClass& operator=(const myClass &iniob);
Добавлено через 27 минут
Сначала конструктор
C++
1
2
3
4
myClass(const char* const a)
{
      *this=charToNum(a);
}
выглядел так же, как и функция преобразования с некоторыми изменениями. Просто её я вынес в отдельный код, чтоб можно было вызывать для преобразований. Похоже сделал это зря. Сейчас всё верну и всё на свои места встать должно. По крайней мере с конструктором.
yekka
384 / 148 / 8
Регистрация: 12.05.2011
Сообщений: 450
13.04.2013, 22:50     Указатель при инициализации не равен NULL #4
если ты считаешь, что myClass(const char* const a) -- это конструктор копирования, то ты ошибаешься
TempuSFatumA
 Аватар для TempuSFatumA
1 / 1 / 0
Регистрация: 02.04.2013
Сообщений: 87
13.04.2013, 22:56  [ТС]     Указатель при инициализации не равен NULL #5
Сделал вариант
C++
1
2
3
4
5
6
    myClass(const char* const a)
{
    this->Ptr=NULL;
    this->Len=0;
    *this=charToNum(a);
}
Всё заработало, как и ожидалось.

Добавлено через 1 минуту
Цитата Сообщение от yekka Посмотреть сообщение
если ты считаешь, что myClass(const char* const a) -- это конструктор копирования, то ты ошибаешься
Я считаю, что это конструктор просто, а не копирования.
Копирование, как я уже сказал, идет при возвращении значения работы функции charToNum(a);

Добавлено через 48 секунд
И это копирование сделано правильно. Инфа 100%.

Добавлено через 3 минуты
Если не понятно, вызов копирования идет в:
C++
1
*this=charToNum(a);
abit
 Аватар для abit
260 / 259 / 33
Регистрация: 03.02.2013
Сообщений: 709
13.04.2013, 23:05     Указатель при инициализации не равен NULL #6
TempuSFatumA,
как то вы не правильно понимаете смысл конструктора копирования

вот код, посмотрите какой конструктор вызывается в данном случае, ваша инфа 100% или нормальный

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
 
class A
{
      public:
      A() { std::cout<<"Default constructor"<<std::endl; };
      A(const char * const a)
      {
              std::cout<<"copy construct 1"<<std::endl;
      }
     A(const A&)
      {
              std::cout<<"copy construct 2"<<std::endl;
      }
};
 
int main()
{
      A a;
      A b=a;
      system("pause");
      return 0;
}
TempuSFatumA
 Аватар для TempuSFatumA
1 / 1 / 0
Регистрация: 02.04.2013
Сообщений: 87
13.04.2013, 23:09  [ТС]     Указатель при инициализации не равен NULL #7
Цитата Сообщение от abit Посмотреть сообщение
TempuSFatumA,
как то вы не правильно понимаете смысл конструктора копирования

вот код, посмотрите какой конструктор вызывается в данном случае, ваша инфа 100% или нормальный

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
 
class A
{
      public:
      A() { std::cout<<"Default constructor"<<std::endl; };
      A(const char * const a)
      {
              std::cout<<"copy construct 1"<<std::endl;
      }
     A(const A&)
      {
              std::cout<<"copy construct 2"<<std::endl;
      }
};
 
int main()
{
      A a;
      A b=a;
      system("pause");
      return 0;
}
Без компиляции могу сказать, что в 1 случае вызывается дефолт, 2 раз- копирование.
В моем же коде идет использование конструктора копирования внутри дефолтного конструктора с параметром конст чар
abit
 Аватар для abit
260 / 259 / 33
Регистрация: 03.02.2013
Сообщений: 709
13.04.2013, 23:10     Указатель при инициализации не равен NULL #8
а чтобы вызвать ваш "конструктор копирования" нужно написать вот такой изврат:
C++
1
2
3
      
      char * p;
      A c(p);
Добавлено через 36 секунд
вот эта штука, как у вас

myClass b=a;

его точно не вызывет
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.04.2013, 23:12     Указатель при инициализации не равен NULL
Еще ссылки по теме:

NULL или проверка инициализации C++
C++ Ошибка нарушения прав доступа при чтении по адресу, возникающая при инициализации трехмерного массива
C++ Как работает нулевой указатель null

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
TempuSFatumA
 Аватар для TempuSFatumA
1 / 1 / 0
Регистрация: 02.04.2013
Сообщений: 87
13.04.2013, 23:12  [ТС]     Указатель при инициализации не равен NULL #9
Просто вы об одном, я о другом, и всё от того, что я криво объяснял всё, моя вина.
Свою проблему я уже решил, холивар и пипкомерство мне не нужны, так что спасибо всем, кто что-либо писал в данной теме.

Добавлено через 1 минуту
Цитата Сообщение от abit Посмотреть сообщение
а чтобы вызвать ваш "конструктор копирования" нужно написать вот такой изврат:
C++
1
2
3
      
      char * p;
      A c(p);
Добавлено через 36 секунд
вот эта штука, как у вас

myClass b=a;

его точно не вызывет
Ну вот, как я и говорю. Не так поняли из-за кривого разъяснения=)
Yandex
Объявления
13.04.2013, 23:12     Указатель при инициализации не равен NULL
Ответ Создать тему
Опции темы

Текущее время: 16:42. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru