dark_rain
|
|
« : 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).
// 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
|
|
« Ответ #1 : 14-07-2011 10:19 » |
|
К сожалению в C++ не особо силён, но похоже Вы два раза освобождаете память, первый раз при выходе из функции foo(), а второй раз по завершении программы.
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #2 : 14-07-2011 10:21 » |
|
Ошибка в том, что у тебя не переопределён конструктор копирования.
Когда ты вызываешь foo, у тебя передаётся и возвращается экземпляр класса A по значению. Конструктор копирования по умолчанию просто копирует содержимое, т.е., указатель i_, который указывает на уже выделенную память, и при уничтожении объектов эта память освобождается несколько раз - точнее, пытается так сделать, потому что сам видишь, чем эти попытки оканчиваются.
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #3 : 14-07-2011 10:32 » |
|
Кстати, массив удалять надо через delete[], а не просто delete.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
dark_rain
|
|
« Ответ #4 : 14-07-2011 12:12 » |
|
Ошибка в том, что у тебя не переопределён конструктор копирования.
Когда ты вызываешь foo, у тебя передаётся и возвращается экземпляр класса A по значению. Конструктор копирования по умолчанию просто копирует содержимое, т.е., указатель i_, который указывает на уже выделенную память, и при уничтожении объектов эта память освобождается несколько раз - точнее, пытается так сделать, потому что сам видишь, чем эти попытки оканчиваются.
Как переопределить конструктор копирования? Или достаточно просто не очищать память во второй раз?
|
|
|
Записан
|
|
|
|
darkelf
Молодой специалист
Offline
|
|
« Ответ #5 : 14-07-2011 12:18 » |
|
Как переопределить конструктор копирования? Или достаточно просто не очищать память во второй раз?
Если не ошибаюсь: A(A&a) { /*do copy there*/ }
|
|
« Последнее редактирование: 14-07-2011 12:20 от darkelf »
|
Записан
|
|
|
|
Вад
|
|
« Ответ #6 : 14-07-2011 13:08 » |
|
К указанному darkelf варианту добавлю от себя, что лучше передавать аргумент константной ссылкой (во избежание). И, в данной реализации не получится адекватно скопировать, поскольку экземпляр ничего не знает о размере массива. Это сигнализирует о том, что класс спроектирован неудачно, и варианты его использования не продуманы. Добавлено через 3 минуты и 46 секунд:Ещё одна проблема - отсутствие явно определённого конструктора по умолчанию. Если сконструировать объект с его помощью, код упадёт: int main() { A a; return 0; } - ведь поле i_ никак не проинциализировано, там мусор, и delete будет удалять неизвестно что. "Повезёт", если конкретный компилятор вставит инициализацию нулём по умолчанию - тогда код будет работать.
|
|
« Последнее редактирование: 14-07-2011 13:13 от Вад »
|
Записан
|
|
|
|
dark_rain
|
|
« Ответ #7 : 14-07-2011 13:47 » |
|
Хорошо, как мне сделать так, что бы память очищалась только раз?
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #8 : 14-07-2011 14:22 » |
|
dark_rain, рекомендую почитать Страуструпа - у него такие вещи хорошо описаны.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Dmitry
Помогающий
Offline
|
|
« Ответ #9 : 15-07-2011 02:20 » |
|
Вы два раза освобождаете память Более того - трижды.
|
|
|
Записан
|
|
|
|
Антон (LogRus)
|
|
« Ответ #10 : 15-07-2011 03:45 » |
|
Я для такого объекта запретил бы копирование (перести в privat конструктор копирования и оператор присваивания), а там где нужно его передавать (в функции например), передавал бы по ссылке или константной ссылке, тоже самое касается возвращаемого значения что же какасается, как сделать что бы память удалялась 1 раз (без запрета копирования объекта), так это сложный и филосовский вопрос, требующий написания многогих букав и рассмотрения конкретных кейсов использования можно сделать подсчёт ссылок, можно использовать умные указатели, в любом случае надо думать и понимать, как именно поведёт себя код и чем придётся заплатить за то или иное решение во многих случаях создание не копируемых объектов довольно разумное решение, во многих нет
|
|
|
Записан
|
Странно всё это....
|
|
|
dark_rain
|
|
« Ответ #11 : 15-07-2011 21:52 » |
|
Господа, всем откликнувшимся - спасибо, по чуть-чуть разбираюсь, активно изучаю посоветованную RXL литературу.
|
|
|
Записан
|
|
|
|
Антон (LogRus)
|
|
« Ответ #12 : 16-07-2011 17:31 » |
|
Я бы к списку добавил Скота Мейрса и Брюса Эккеля, имхо они легче и тоньше
|
|
|
Записан
|
Странно всё это....
|
|
|
dark_rain
|
|
« Ответ #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
Спокойный
Администратор
Offline
Пол:
Пролетал мимо
|
|
« Ответ #14 : 18-07-2011 19:43 » |
|
Что то типа этого? #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
|
|
« Ответ #15 : 18-07-2011 19:56 » |
|
Добрый человек! Я даже и не знаю как тебя благодарить!!! СПАСИБО!!!!!!!!!!!!!!
|
|
|
Записан
|
|
|
|
Антон (LogRus)
|
|
« Ответ #16 : 19-07-2011 03:58 » |
|
dark_rain, думаю Finch удовлетворится тем, что ты про Весельчака не забудешь и будешь читать умные книги
|
|
|
Записан
|
Странно всё это....
|
|
|
dark_rain
|
|
« Ответ #17 : 19-07-2011 06:59 » |
|
Антон (LogRus), а как же! Не забуду - ресурс замечательный А насчет книг - штудирую, хочу стать специалистом в этой области!
|
|
|
Записан
|
|
|
|
|