Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Помогите найти ошибку, компилируется но не выполняется.  (Прочитано 17503 раз)
0 Пользователей и 1 Гость смотрят эту тему.
dark_rain
Помогающий

ua
Offline Offline
Пол: Мужской

« : 14-07-2011 08:41 » new

Не могу понять в чем ошибка, думаю, что в указателе int* i_ или в этой строке i_=new int.
Вылетает с кодом
 
Цитата
The thread 'Win32 Thread' (0x998) has exited with code -1073741510 (0xc000013a).
The thread 'Main Thread' (0x564) has exited with code -1073741510 (0xc000013a).
The program '[3252] Tested.exe: Native' has exited with code -1073741510 (0xc000013a).


Код: (C++)
// Tested.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"


class A
{
public:
        A(int i)
        {
                i_=new int[i];
        }
        ~A()
        {
                delete i_;
        }
private:
                int* i_;
};
A foo(A a)
{
        return a;
}

int main()
{
        A a(100);
        foo(a);
        return 0;
}

« Последнее редактирование: 14-07-2011 10:27 от Джон » Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #1 : 14-07-2011 10:19 » 

К сожалению в C++ не особо силён, но похоже Вы два раза освобождаете память, первый раз при выходе из функции foo(), а второй раз по завершении программы.
Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 14-07-2011 10:21 » 

Ошибка в том, что у тебя не переопределён конструктор копирования.

Когда ты вызываешь foo, у тебя передаётся и возвращается экземпляр класса A по значению. Конструктор копирования по умолчанию просто копирует содержимое, т.е., указатель i_, который указывает на уже выделенную память, и при уничтожении объектов эта память освобождается несколько раз - точнее, пытается так сделать, потому что сам видишь, чем эти попытки оканчиваются.
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 14-07-2011 10:32 » 

Кстати, массив удалять надо через delete[], а не просто delete.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
dark_rain
Помогающий

ua
Offline Offline
Пол: Мужской

« Ответ #4 : 14-07-2011 12:12 » 

Ошибка в том, что у тебя не переопределён конструктор копирования.

Когда ты вызываешь foo, у тебя передаётся и возвращается экземпляр класса A по значению. Конструктор копирования по умолчанию просто копирует содержимое, т.е., указатель i_, который указывает на уже выделенную память, и при уничтожении объектов эта память освобождается несколько раз - точнее, пытается так сделать, потому что сам видишь, чем эти попытки оканчиваются.
Как переопределить конструктор копирования? Или достаточно просто не очищать память во второй раз?
Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #5 : 14-07-2011 12:18 » 

Как переопределить конструктор копирования? Или достаточно просто не очищать память во второй раз?
Если не ошибаюсь:
Код:
A(A&a)
{ /*do copy there*/
}
« Последнее редактирование: 14-07-2011 12:20 от darkelf » Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 14-07-2011 13:08 » 

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

И, в данной реализации не получится адекватно скопировать, поскольку экземпляр ничего не знает о размере массива. Это сигнализирует о том, что класс спроектирован неудачно, и варианты его использования не продуманы.

Добавлено через 3 минуты и 46 секунд:
Ещё одна проблема - отсутствие явно определённого конструктора по умолчанию. Если сконструировать объект с его помощью, код упадёт:
Код: (C++)
int main() {
  A a;
  return 0;
}
- ведь поле i_ никак не проинциализировано, там мусор, и delete будет удалять неизвестно что. "Повезёт", если конкретный компилятор вставит инициализацию нулём по умолчанию - тогда код будет работать.
« Последнее редактирование: 14-07-2011 13:13 от Вад » Записан
dark_rain
Помогающий

ua
Offline Offline
Пол: Мужской

« Ответ #7 : 14-07-2011 13:47 » 

Хорошо, как мне сделать так, что бы память очищалась только раз?
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #8 : 14-07-2011 14:22 » 

dark_rain, рекомендую почитать Страуструпа - у него такие вещи хорошо описаны.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dmitry
Помогающий

ru
Offline Offline

« Ответ #9 : 15-07-2011 02:20 » 

Вы два раза освобождаете память
Более того - трижды.
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #10 : 15-07-2011 03:45 » 

Я для такого объекта запретил бы копирование (перести в privat конструктор копирования и оператор присваивания), а там где нужно его передавать (в функции например), передавал бы по ссылке или константной ссылке, тоже самое касается возвращаемого значения
что же какасается, как сделать что бы память удалялась 1 раз (без запрета копирования объекта), так это сложный и филосовский вопрос, требующий написания многогих букав и рассмотрения конкретных кейсов использования
можно сделать подсчёт ссылок, можно использовать умные указатели, в любом случае надо думать и понимать, как именно поведёт себя код и чем придётся заплатить за то или иное решение
во многих случаях создание не копируемых объектов довольно разумное решение, во многих нет
Записан

Странно всё это....
dark_rain
Помогающий

ua
Offline Offline
Пол: Мужской

« Ответ #11 : 15-07-2011 21:52 » 

Господа, всем откликнувшимся - спасибо, по чуть-чуть разбираюсь, активно изучаю посоветованную RXL литературу.
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #12 : 16-07-2011 17:31 » 

Я бы к списку добавил Скота Мейрса и Брюса Эккеля, имхо они легче и тоньше
Записан

Странно всё это....
dark_rain
Помогающий

ua
Offline Offline
Пол: Мужской

« Ответ #13 : 16-07-2011 18:19 » 

Спасибо, ознакомлюсь.

Добавлено через 2 дня, 59 минут и 40 секунд:
Господа, прошу помощи! Никак не могу нормально переопределить конструктор копирования... Что только не делал! Изучаю указанную литературу, но на конкретном примере применить не могу. Проблема у меня с ф-цией foo. Вот если  ее не вызывать то все превосходно, но в таком случае это уже не конкретный пример.

Код:
#include "stdafx.h"
#include <iostream>

class A
{
public:
        A(int i)
        {
                i_=new int[i];
        }
A(const A&a)
{
}
        ~A()
        {
                delete i_;
        }
private:
                int* i_;
};
A foo(A a)
{
        return a;
}

int main()
{
        A a(100);
        foo(a);
        return 0;
}
Это то, что я имею на данный момент... Подскажите еще, что мне нужно сделать с указателем  "int* i_;"?
« Последнее редактирование: 18-07-2011 19:18 от dark_rain » Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #14 : 18-07-2011 19:43 » 

Что то типа этого?
Код: (C++)
#include <iostream>

class A
{
public:
        A()
        {
            len = 0;
            i_ = NULL;
            std::cout << "Constructor A()" << std::endl;
        }

    A(int i)
    {
        i_=new int[i];
        len = i;
            std::cout << "Constructor A("<< i <<")" << std::endl;
    }

    A(const A&a)
        {
            if (a.len >0)
            {
                i_ = new int[a.len];
                len = a.len;
                for(int beg = 0; beg < len; beg++)
                {
                   i_[beg] = a.i_[beg];
                }
            std::cout << "Constructor A(a("<< a.len <<"))" << std::endl;

            }
    }
   
    ~A()
    {
        delete [] i_;
        len = 0;
            std::cout << "Destructor" << std::endl;

    }
private:
    int* i_;
    int len;
};

A foo(A a)
{
        return a;
}

int main()
{
        A a(100);
        foo(a);
        return 0;
}
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
dark_rain
Помогающий

ua
Offline Offline
Пол: Мужской

« Ответ #15 : 18-07-2011 19:56 » 

Добрый человек! Я даже и не знаю как тебя благодарить!!! СПАСИБО!!!!!!!!!!!!!!
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #16 : 19-07-2011 03:58 » 

dark_rain, думаю Finch удовлетворится тем, что ты про Весельчака не забудешь и будешь читать умные книги Улыбаюсь
Записан

Странно всё это....
dark_rain
Помогающий

ua
Offline Offline
Пол: Мужской

« Ответ #17 : 19-07-2011 06:59 » 

Антон (LogRus), а как же! Не забуду - ресурс замечательный Улыбаюсь А насчет книг - штудирую, хочу стать специалистом в этой области!
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines