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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
igor_kz
150 / 150 / 12
Регистрация: 16.06.2012
Сообщений: 312
#1

Правильная инициализация ? - C++

18.11.2013, 11:24. Просмотров 350. Ответов 3
Метки нет (Все метки)

Здравствуйте уважаемые программисты!
Мне необходимо описать два класса, один ArrayOfInt - якобы одномерный массив, и SqArrayOfInt - уже двумерный массив, основанный на массиве ArrayOfInt.
Моя проблема: после инициализации случайными числами, матрица получается не той что должна быть.
Например: после вызова функции из 37 строки, данные выводятся верные, а уже на 41 (хотя один и тот же вызов, только прошла инициализация всей матрицы) уже совсем другие числа.
Думаю, что проблема где-то в конструкторе, но не виду в чем именно.
Среда: Code::Blocks 10.05
Спасибо!

ArrayOfInt
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#ifndef ARRAY_OF_INT
#define ARRAY_OF_INT
 
class ArrayOfInt
{
public:
  ArrayOfInt(int size); // конструктор
  ArrayOfInt();
  ~ArrayOfInt();        // деструктор
 
  int getSize();        // возвращает размер массива
  void setSize(int size);
 
  int get(int index);       // метод доступа к элементам массива
  void set(int index, int value); // метод установки элементов массива
 
  int sum();                //вычисление суммы чисел в массиве
  // Метод сортировки массива по возрастанию и по убыванию:
  void sort(bool isIncrease);
  // методы сравнения двух массивов (==, !=):
  bool operator ==(ArrayOfInt& array);
  bool operator !=(ArrayOfInt& array);
  // Метод конкатенации (слияния) двух массивов:
  ArrayOfInt& concatenation(ArrayOfInt& array);
 
private:
  int *p_;              // указатель на массив
  int size_;            // размер массива
};
 
#endif  // ARRAY_OF_INT
 
#include "ArrayOfInt.h"
 
ArrayOfInt::ArrayOfInt(int size)
{
    delete []p_;
    this->size_ = size;
    p_ = new int[size_];
    for (int i = 0; i < size_; i++)
        p_[i] = 0;
}
 
ArrayOfInt::ArrayOfInt()
{
    this->size_ = 0;
    p_ = new int[size_];
}
 
ArrayOfInt::~ArrayOfInt()
{
  delete []p_;
}
 
int ArrayOfInt::getSize()
{
  return size_;
}
 
void ArrayOfInt::setSize(int size) {
    this->size_ = size;
}
 
int ArrayOfInt::get(int index)
{
  return p_[index];
}
 
void ArrayOfInt::set(int index, int value)
{
  p_[index] = value;
}
 
int ArrayOfInt::sum()
{
  int s = 0;
  for (int i = 0; i < size_; i++)
    s += p_[i];
  return s;
}
 
void ArrayOfInt::sort(bool isIncrease)
{
  int buf;
  //сортировка массива методом пузырька:
  for(int i = 0; i < size_; i++) {
    for(int j = 0; j < size_ - 1; j++) {
      if (isIncrease && p_[j] > p_[j + 1]
          || !isIncrease && p_[j] < p_[j + 1]) {
        buf = p_[j];
        p_[j] = p_[j + 1];
        p_[j + 1] = buf;
      }
    }
  }
}
 
bool ArrayOfInt::operator ==(ArrayOfInt& array)
{
  if (size_ != array.getSize())
    return false;
 
  for(int i = 0; i < size_; i++) {
    if (p_[i] != array.get(i))
      return false;
  }
  return true;
}
 
bool ArrayOfInt::operator !=(ArrayOfInt& array)
{
  return !(*this == array);
}
 
ArrayOfInt& ArrayOfInt::concatenation(ArrayOfInt& array)
{
  ArrayOfInt tempArray(size_);
 
  int i;
  for(i = 0; i < size_; i++) {
    tempArray.set(i, p_[i]);
  }
 
  delete []p_;
  int newSize = size_ + array.getSize();
  p_ = new int[newSize];
 
  for(i = 0; i < size_; i++) {
    p_[i] = tempArray.get(i);
  }
 
  for(int j = 0; j < array.getSize(); j++) {
    p_[i++] = array.get(j);
  }
 
  size_ = newSize;
 
  return *this;
}


SQ_ARRAY
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include "ArrayOfInt.cpp"
 
#ifndef SQ_ARRAY_OF_INT
#define SQ_ARRAY_OF_INT
 
class SqArrayOfInt
{
public:
  SqArrayOfInt(int size); // конструктор
  ~SqArrayOfInt();        // деструктор
 
  int getSize();        // возвращает размер массива
 
  ArrayOfInt& get(int index);       // метод доступа к элементам массива
  void set(int index, ArrayOfInt& value); // метод установки элементов массива
 
  int sum();                //вычисление суммы чисел в массиве
  // Метод сортировки массива по возрастанию и по убыванию:
  void sort(bool isIncrease);
  // методы сравнения двух массивов (==, !=):
  bool operator ==(SqArrayOfInt& array);
  bool operator !=(SqArrayOfInt& array);
  // Метод конкатенации (слияния) двух массивов:
  SqArrayOfInt& concatenation(SqArrayOfInt& array);
 
private:
  ArrayOfInt *p_;              // указатель на массив
  int size_;            // размер массива
};
 
#endif
 
#include "SqArrayOfInt.h"
#include <iostream>
SqArrayOfInt::SqArrayOfInt(int size)
{
    this->size_ = size;
    p_ = new ArrayOfInt[size_];
    for (int i = 0 ; i < size ; i++) {
        ArrayOfInt t(size);
        p_[i] = t;
    }
}
 
SqArrayOfInt::~SqArrayOfInt()
{
  delete []p_;
}
 
int SqArrayOfInt::getSize()
{
  return size_;
}
 
 
ArrayOfInt& SqArrayOfInt::get(int index)
{
  return p_[index];
}
 
void SqArrayOfInt::set(int index, ArrayOfInt& value)
{
    p_[index].setSize(value.getSize());
    for (int i = 0 ; i < p_[index].getSize() ; i++) {
        p_[index].set(i , value.get(i));
    }
}
 
int SqArrayOfInt::sum()
{
    int s = 0;
    for (int i = 0; i < size_; i++)
        for (int j = 0 ; j < p_[i].getSize() ; j++)
            s += p_[i].get(j);
    return s;
}
 
void SqArrayOfInt::sort(bool isIncrease)
{
  int buf;
  //сортировка массива методом пузырька:
    for(int row = 0; row < size_; row++) { //выбираем строку для сортировки
        for (int i = 0 ; i < p_[row].getSize() ; i++) {
            for (int j = 0; j < p_[row].getSize() - 1; j++) {
                if (isIncrease && p_[row].get(j) > p_[row].get(j + 1)
                    || !isIncrease && p_[row].get(j) < p_[row].get(j + 1)) {
                        buf = p_[row].get(j); p_[row].set(j , p_[row].get(j + 1));  p_[row].set(j + 1 , buf);
                }
            }
        }
    }
}
 
bool SqArrayOfInt::operator ==(SqArrayOfInt& array)
{
    if (size_ != array.getSize())
        return false;
    for (int i = 0 ; i < size_ ; i++) {
        if (this->p_[i].getSize() != array.p_[i].getSize())
            return false;
        for (int j = 0 ; j < array.p_[i].getSize() ; j++)
            if (this->p_[i].get(j) != array.p_[i].get(j))
                return false;
    }
    return true;
}
 
bool SqArrayOfInt::operator !=(SqArrayOfInt& array)
{
  return !(*this == array);
}
 
SqArrayOfInt& SqArrayOfInt::concatenation(SqArrayOfInt& array)
{
    SqArrayOfInt tempArray(size_);
    int i;
    for (i = 0; i < size_; i++) {
        tempArray.set(i, p_[i]);
    }
    delete []p_;
    int newSize = size_ + array.getSize();
    p_ = new ArrayOfInt[newSize];
    for (i = 0; i < size_; i++) {
        p_[i] = tempArray.get(i);
    }
    for (int j = 0; j < array.getSize(); j++) {
        p_[i++] = array.get(j);
    }
    size_ = newSize;
    return *this;
}

main
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
100
#include "SqArrayOfInt.cpp"
#include <iostream>
#include <conio.h>
#include <time.h>
#include <cstdlib>
 
using namespace std;
 
void showArray(ArrayOfInt& array) // вывод массива на экран
{
    cout << "Vector size: " << array.getSize() << endl;
    for (int i = 0; i < array.getSize(); i++) {
        cout << array.get(i) << " ";
    }
    cout << endl;
}
void showArray(SqArrayOfInt& array) // вывод массива на экран
{
    cout << "Matrix size: " << array.getSize() << endl;
    for (int i = 0; i < array.getSize(); i++) {
        showArray(array.get(i));
    }
}
 
int main()
{
    SqArrayOfInt arr(3);
    showArray(arr);
    // установка начальной точки для генерации псевдослучайных целых чисел:
    srand ((unsigned int)time(NULL));
    // заполнение массива:
    for (int i = 0; i < arr.getSize(); i++) {
        ArrayOfInt t(3);
        for (int j = 0 ; j < 3 ; j++)
            t.set(j , rand() % 10);
        arr.set(i , t);
        showArray(arr.get(i));
    }
 
    for (int i = 0 ; i < 3 ; i++)
        showArray(arr.get(i));
 
    cout << endl << endl;
    // вывод массива на экран:
    cout << "Array 1:" << endl;
    showArray(arr);
  /*
  // вычисление и вывод на экран суммы чисел в массиве:
  cout << endl << "Array 1 sum = " << arr.sum() << endl;
 
  // сортировки массива по убыванию:
  arr.sort(false);
  cout << "Decrease Sorted array 1:" << endl;
  showArray(arr);
 
  ArrayOfInt arr2(10);
 
  // заполнение массива:
  for (int i = 0; i < arr2.getSize(); i++)
    arr2.set(i, rand() % 10);
  // вывод массива на экран:
  cout << endl << "Array 2:" << endl;
  showArray(arr2);
 
  cout << endl;
  //сравнение массивов:
  if( arr == arr2)
    cout <<  "Array 1 == Array 2";
  else
    cout << "Array 1 != Array 2";
 
  // сортировки массива по возрастанию:
  arr.sort (true);
  cout << endl << "Increase Sorted array 1:" << endl;
  // вывод массива на экран:
  showArray(arr);
 
  cout << endl;
  //сравнение массивов:
  if( arr == arr2)
    cout << "Array 1 == Array 2";
  else
    cout << "Array 1 != Array 2";
 
  // заполнение массива:
  for (int i = 0; i < arr2.getSize(); i++)
    arr2.set(i, rand() % 100);
 
  // вывод массива на экран:
  cout << endl << "Array 2:" << endl;
  showArray(arr2);
 
  //конкатенация (слияния) двух массивов:
  arr.concatenation(arr2);
  cout << endl << "Array 1 (concatenated with array 2):" << endl;
  // вывод массива на экран:
  showArray(arr);
  */
  _getch();
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.11.2013, 11:24     Правильная инициализация ?
Посмотрите здесь:

C++ Не правильная структура и где?
C++ Правильная дата
C++ Правильная перезагрузка оператора ''=''
Правильная скобочная последовательность C++
правильная перегрузка операторов C++
Правильная очистка памяти C++
C++ Правильная линковка библиотек
C++ Правильная ли программа?
C++ Не правильная обработка массивов
Правильная скобочная последовательность C++
Правильная скобочная последовательность C++
C++ Правильная компиляция

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Peregrin
33 / 33 / 1
Регистрация: 16.11.2012
Сообщений: 59
18.11.2013, 13:49     Правильная инициализация ? #2
C++
1
2
3
4
5
6
7
for (int i = 0; i < arr.getSize(); i++) {
        ArrayOfInt t(3);
        for (int j = 0 ; j < 3 ; j++)
            t.set(j , rand() % 10);
        arr.set(i , t);
        showArray(arr.get(i));
    }
В arr.set(i,t) ты передаёшь адрес локальной переменной, для которой в конце итерации цикла вызывается деструктор, который и затирает эту локальную переменную. Я бы в SQ_ARRAY сделал
C++
1
void set(int index, ArrayOfInt value);
вместо
C++
1
void set(int index, ArrayOfInt& value);
т.е. передавал бы копию, тогда всё нормально будет (ну только если тебе не жалко процессорное время на копировани ArrayOfInt ).
igor_kz
150 / 150 / 12
Регистрация: 16.06.2012
Сообщений: 312
18.11.2013, 13:59  [ТС]     Правильная инициализация ? #3
Спасибо за ответ!
Что-то нахимичил, вроде работает
Менял не это, а там в некоторых местах размер массива не обновлял(
alsav22
5413 / 4809 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
18.11.2013, 23:40     Правильная инициализация ? #4
Ваш код, в студии, вот здесь исключение выбрасывает:
C++
1
2
3
4
5
6
7
8
ArrayOfInt::ArrayOfInt(int size)
{
    //delete [] p_; // удаление по неинициализированному указателю
    this->size_ = size;
    p_ = new int[size_];
    for (int i = 0; i < size_; i++)
        p_[i] = 0;
}
Если у вас нет исключения, то значит компилятор обнуляет неинициализированные указатели, но это всё равно кривизна кода.
Если у вас в классе есть поля-указатели, то обязательно определяют конструктор копирования и присваивания.
Вот здесь происходит присваивание объектов ArrayOfInt:
C++
1
2
3
4
5
6
7
8
9
SqArrayOfInt::SqArrayOfInt(int size)
{
    this->size_ = size;
    p_ = new ArrayOfInt[size_];
    for (int i = 0 ; i < size ; i++) {
        ArrayOfInt t(size);
        p_[i] = t; // присваивание
    }
}
Так как оператор присваивания не определён явно, то работает тот, который по умолчанию. Он просто копирует указатели. В данном случае, это указатель, который находится в локальном объекте t, и который уничнтожается при каждой новой итерации, при этом память, с которой связан указаетль в t, освобождается деструктором.

Добавлено через 11 минут
А для того, чтобы работало то, что предложил Peregrin, как раз нужен явно заданный конструктор копирования(для передачи объекта по значению). Хотя делать так, как предложил Peregrin необязательно. Объект локальный, но сохраняется в нелокальном объекте (arr), после чего становится уже ненужным.
Yandex
Объявления
18.11.2013, 23:40     Правильная инициализация ?
Ответ Создать тему
Опции темы

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