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

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

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

« : 14-07-2011 08:41 » 

Не могу понять в чем ошибка, думаю, что в указателе 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
Молодой специалист

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
Молодой специалист

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
Технический
Администратор

ru
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