Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
EfesXZC
2 / 2 / 2
Регистрация: 07.08.2015
Сообщений: 72
#1

Вылет программы при создании объекта - C++

10.10.2015, 18:25. Просмотров 1122. Ответов 54
Метки нет (Все метки)

Начал изучать классы с создания класса для работы с массивами, класс должен работать как с одномерными так и двумерными динамическими массивами. Но возникла проблема: программа отчего-то вылетает при создании объекта. С чем это может быть связано?
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
class Massiv {
private:
    int N;
    int *mas_1;
    int **mas_2;
    int R, C;
public:
    Massiv(){                 //конструктор без параметров
    }
 
    Massiv(int size)          // конструктор одномерного массива
        {
            N = size;
            mas_1 = new int [N];
            for(int i = 0; i < N; i++)
               {
                  mas_1[i] = 0;
               }
        }
 
 
    Massiv(int rows, int columns )                  //конструктор двумерного массива
    {
        R = rows;
        C = columns;
        mas_2 = new int* [R];                       // R строк в массиве
            for (int i = 0; i < R; i++)
                mas_2[i] = new int [C];             // и С столбцов
 
            for (int i_row = 0; i_row < R; i_row++)
                    for (int j_column = 0; j_column < C; j_column++)
                        mas_2[i_row][j_column] = 0;
    }
 
 
    ~Massiv()
    {
        //высвобождение памяти отводимой под одномерный динамический массив:
        delete []mas_1;
 
        // высвобождение памяти отводимой под двумерный динамический массив:
        for (int i = 0; i < R; i++)
            delete [] mas_2[i];
    }
 
    int &operator[](int j)      //перегрузка [] для индексации одномерного массива
        {
            return mas_1[j];
        }
 
    void showData()                 //вывод одномерного массива на экран
        {
            for(int i = 0; i < N; i++)
            {
                cout << mas_1[i] << " | ";
            }
        }
 
    void showData_2()               //вывод двумерного массива на экран
        {
        for (int i_row = 0; i_row < R; i_row++)
            {
                for (int j_column = 0; j_column < C; j_column++)
                    cout << mas_2[i_row][j_column] << "   ";
                    cout << endl;
            }
        }
 
    void addNumber_arm()            //Ручной ввод данных одномерного массива
    {
        for(int i = 0; i < N; i++)
        {
            cin >> mas_1[i];
        }
    }
 
    void addNumber_rand_2()        //Рандомный ввод данных двумерного массива
    {
        for (int i_row = 0; i_row < R; i_row++)
                for (int j_column = 0; j_column < C; j_column++)
                    mas_2[i_row][j_column] = (rand() % 10 + 1) / int((rand() % 10 + 1));
    }
 
    void addNumber_arm_2()        //Ручной ввод данных двумерного массива
    {
        for (int i_row = 0; i_row < R; i_row++)
                for (int j_column = 0; j_column < C; j_column++)
                    cin >> mas_2[i_row][j_column];
    }
 
    void deleteIData_1(int x)     //Удаление i-ого элемента одномерного массива
    {
        for(int i = x; i < N; i++)
        {
            mas_1[i] = mas_1[i+1];
        }
       N--;
    }
};
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.10.2015, 18:25
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Вылет программы при создании объекта (C++):

Вылет из программы при выполнении
Вот ф-ция из-за которой вылетает программа.Ф-ция считает среднее...

Вылет при работе программы с неизвестной ошибкой
#include &lt;iostream&gt; #include &lt;cstring&gt; using namespace std; int main()...

Вылет программы при удалении динамического массива
Писал программу с использованием динамического массива, все компилилось...

Ошибка при создании объекта класса
Приветствую, форумчане! Возник вопрос при создании объекта класса String. Что...

Ошибка при создании объекта класса
Здравствуйте. В коде ниже при попытке вывести код на экран возникает следующая...

Undefined reference при создании объекта
Есть класс Engine и функция для его инициализации - CreateEngine при попытке...

54
Fulcrum_013
Заблокирован
15.10.2015, 22:32 #41
Ну тут два варианта возможны. Первый - оставить себя неизменным и вернуть новую транспанированную матрицу. Это значит создать новый объект и скопировать в него данные из себя повернутыми, и вернуть этот новый объект а не внутренний буффер. Второй подход повернуть именно себя повернутого. (какой нужен зависит от задачи, часто делают два метода под каждый вариант).
Для второго варианта если он идет с пересозданием буффера (вообще для подобных задач, включая ресайз) последовательность действий такова:
создать новый буффер
скопировать данные из старого
удалить старый
в указатели объекта переписать указатели из локальных переменных, указывающие на новый буффер.

При выделении памяти под массив одним куском задача транспонирования решается вообще без перераспределения основного буффера. Для этого достаточно переставить нужным образом элементы, после чего перекроить массив указателей на строки.
0
EfesXZC
2 / 2 / 2
Регистрация: 07.08.2015
Сообщений: 72
16.10.2015, 19:00  [ТС] #42
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
достаточно переставить нужным образом элементы
Собственно, из-за этого я и отказался от подобного выделения памяти, т.к. не придумал алгоритма перестановки элементов.
0
Fulcrum_013
Заблокирован
16.10.2015, 20:29 #43
Цитата Сообщение от EfesXZC Посмотреть сообщение
Собственно, из-за этого я и отказался от подобного выделения памяти, т.к. не придумал алгоритма перестановки элементов.
Ну для квадратной матрицы алгоритм прост до ужаса. идете до главной диагонали и меняете элемент с его зеркальным отражением относительно главной диагонали. Для неквадратных - то что в квадрат попадает точно так же, а то что не попадает - для него индексы пересчитываются. Опять же принцип распределил новое, переписал данные, удалил старое, переписал в глобальное хранилище (переменные объекта) указатели на новое - работает при любом способе распределения.
0
EfesXZC
2 / 2 / 2
Регистрация: 07.08.2015
Сообщений: 72
16.10.2015, 23:22  [ТС] #44
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
и вернуть этот новый объект а не внутренний буффер
Возникла похожая ситуация в перегрузке оператора умножения. При попытке вернуть объект из функции, программа закрывается. А если точнее, она закрывается при попытке присвоить произведение двух объектов третьему объекту. Не могу понять в чем дело.

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
31
32
33
34
35
36
37
38
39
40
//matrix.cpp
Matrix & Matrix::operator* (const Matrix & m)                               //Перегрузка оператора * для умножения двух матриц
{
    Matrix temp(rowsCount, m.colCount);
    if (rowsCount == m.colCount)
    {
        for (int i = 0; i < rowsCount; ++i)
            for (int j = 0; j < m.colCount; ++j){
              temp.inx(i, j) = 0;
                for(int c = 0; c < m.rowsCount; c++) {
                    temp.inx(i, j) += common_block[i][c] * m.common_block[c][j];
                }
            }
    }
 
    return temp;
 
Matrix & Matrix::operator= (const Matrix & m)                             //Перегрузка оператора =
{
    if (this != &m)
    {
        for (int count = 0; count < rowsCount; count++)
                delete [] common_block[count];
        delete [] common_block;
 
        rowsCount = m.rowsCount;
        colCount = m.colCount;
 
        common_block = new int * [rowsCount];
        for (int i = 0; i < rowsCount; ++i)
            common_block[i] = new int [colCount];
 
        for (int i = 0; i < rowsCount; ++i)
            for (int j = 0; j < colCount; ++j)
                common_block[i][j] = m.common_block[i][j];
    }
    return *this;
}
 
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//main.cpp
int main (){
 
    Matrix mas_1(2, 3);
    Matrix mas_2(3, 2);
    Matrix mas_3(2, 2);
 
    mas_1.fill_rand(0, 10);
    mas_2.fill_rand(0, 10);
 
    mas_1.getMatrix();
    mas_2.getMatrix();
 
    mas_3 = (mas_1 * mas_2);
 // mas_3.getMatrix();
 // int a = mas_3.inx(1, 1);
 // cout << a << endl;
    return 0;
}
0
Renji
2141 / 1500 / 456
Регистрация: 05.06.2014
Сообщений: 4,338
16.10.2015, 23:59 #45
Цитата Сообщение от EfesXZC Посмотреть сообщение
При попытке вернуть объект из функции, программа закрывается. А если точнее, она закрывается при попытке присвоить произведение двух объектов третьему объекту. Не могу понять в чем дело.
Дело в том что возвращается не объект, а ссылка на него. А сам объект сразу же по завершении функции прибивается, потому как локальный. Поменяйте Matrix & на Matrix и запилите перемещающий и копирующий конструкторы.
1
Fulcrum_013
Заблокирован
17.10.2015, 00:20 #46
Цитата Сообщение от Renji Посмотреть сообщение
Дело в том что возвращается не объект, а ссылка на него. А сам объект сразу же по завершении функции прибивается, потому как локальный.
Вообще в таком случае должна быть ошибка компиляции. У меня компилятор в таких случаях так и ругается "attempt to return reference to local object"
0
EfesXZC
2 / 2 / 2
Регистрация: 07.08.2015
Сообщений: 72
17.10.2015, 17:09  [ТС] #47
Цитата Сообщение от Renji Посмотреть сообщение
Поменяйте Matrix & на Matrix и запилите перемещающий и копирующий конструкторы.
Renji, теперь из функции возвращаю объект. И сделал копирующий конструктор. Который, как я понимаю, вызывается неявно при возвращении объекта? А по перемещающему конструктору я почти не нашел никакой инфы и примеров реализации, поэтому был бы благодарен, если вы поделитесь.
0
Renji
2141 / 1500 / 456
Регистрация: 05.06.2014
Сообщений: 4,338
17.10.2015, 17:18 #48
Цитата Сообщение от EfesXZC Посмотреть сообщение
Renji, теперь из функции возвращаю объект. И сделал копирующий конструктор. Который, как я понимаю, вызывается неявно при возвращении объекта?
Да, вызывается неявно. Или не вызывается, если с оптимизацией кода повезет. Но лучше на это не полагаться.
Цитата Сообщение от EfesXZC Посмотреть сообщение
А по перемещающему конструктору я почти не нашел никакой инфы и примеров реализации, поэтому был бы благодарен, если вы поделитесь.
Перемещающий конструктор, это такой конструктор, который принимает на вход Matrix&&src и тащит из src абсолютно все, кроме необходимого для корректной работы деструктора src. Как раз самое то для перемещения объекта из функции во внешний мир, потому как после return локальной копией объекта все равно никто пользоваться не будет.
C++
1
2
3
4
5
6
Matrix::Matrix(Matrix&&src):common_block(src.common_block),rowsCount(src.rowsCount),colCount(src.colCount)
{
    src.common_block=nullptr;
    src.rowsCount=0;
    src.colCount=0;
}
1
EfesXZC
2 / 2 / 2
Регистрация: 07.08.2015
Сообщений: 72
17.10.2015, 17:21  [ТС] #49
Renji, а если будут и конструктор копирования и конструктор перемещения, какой из них будет вызываться после return?
0
Renji
2141 / 1500 / 456
Регистрация: 05.06.2014
Сообщений: 4,338
17.10.2015, 17:45 #50
Цитата Сообщение от EfesXZC Посмотреть сообщение
Renji, а если будут и конструктор копирования и конструктор перемещения, какой из них будет вызываться после return?
Перемещающий, если есть.
0
EfesXZC
2 / 2 / 2
Регистрация: 07.08.2015
Сообщений: 72
17.10.2015, 18:51  [ТС] #51
Renji, похоже мой компилятор категорически не одобряет конструкторы перемещения
0
Миниатюры
Вылет программы при создании объекта  
Renji
2141 / 1500 / 456
Регистрация: 05.06.2014
Сообщений: 4,338
17.10.2015, 18:54 #52
Цитата Сообщение от EfesXZC Посмотреть сообщение
Renji, похоже мой компилятор категорически не одобряет конструкторы перемещения
QMAKE_CXXFLAGS += -std=c++11 в pro файл, если это QtCreator.
0
EfesXZC
2 / 2 / 2
Регистрация: 07.08.2015
Сообщений: 72
17.10.2015, 19:09  [ТС] #53
Renji, уже прописано

Добавлено через 13 минут
Видимо, дело не в этом
0
Renji
2141 / 1500 / 456
Регистрация: 05.06.2014
Сообщений: 4,338
17.10.2015, 19:35 #54
Попробуйте Matrix::Matrix заменить на Matrix. По идее, внутри объявления класса Matrix:: быть не должно. Может быть на этом споткнулось.
0
EfesXZC
2 / 2 / 2
Регистрация: 07.08.2015
Сообщений: 72
17.10.2015, 20:09  [ТС] #55
Renji, не. Уже пробовал. Не помогает
0
17.10.2015, 20:09
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.10.2015, 20:09
Привет! Вот еще темы с решениями:

Как работает компилятор при создании объекта
Таки думал разобрался как работает конструктор копирования, а выходит, что нет....

Ошибка LNK2019 При динамическом создании объекта
Это хидер который я создал #include&lt;math.h&gt; #define PI 3.14 class Figure...

Ошибки при создании объекта в другом файле
a.h struct Coords { int x; int y; Coords() {}; Coords(int mX, int...

Ключевое слово class при создании объекта
class A { int r; }; int main () { class A w;//Для чего здесь...


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

Или воспользуйтесь поиском по форуму:
55
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru