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

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

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

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

18.11.2013, 11:24. Просмотров 366. Ответов 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++
#indlude &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std; int main() { int Fedya = 40; cout &lt;&lt; &quot;Force indicator&quot;...

Правильная дата - C++
Даны три натуральных чисел, B, C, которые представляют день, месяц и год некоторые даты. Выход &quot;да&quot;, если указанной даты является...

Правильная ли программа? - C++
Не уверена в правильности соответствия задания и кода. Обычно ведь очередь через структуру делается. Задание следующее: Создать класс -...

Правильная перезагрузка оператора ''='' - C++
совсем недавно начал работать с шаблонами, и возникла такая проблема: имеется шаблонный класс - вектор: template&lt;class T&gt; class...

Правильная скобочная последовательность - 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
Спасибо за ответ!
Что-то нахимичил, вроде работает
Менял не это, а там в некоторых местах размер массива не обновлял(
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.11.2013, 23:40     Правильная инициализация ?
Еще ссылки по теме:

Правильная линковка библиотек - C++
Долго искал в интернете, ничего толкового не нашёл, решил спросить тут. После создания приложения компилятор прицепляет файл статически,...

Правильная очистка памяти - C++
Пытаюсь разобратся с работой с памятью в с++. Есть класс BigInteger содержащий в себе массив чисел int *arr. В конструкторе этот массив...

Не правильная обработка массивов - C++
Возникла проблема: При работе функции read_struct не обрабатываются gets(x.name); и gets(x.date_of_birth); с чем это связано? Есть вот...

Правильная скобочная последовательность - C++
Привет, не могу понять как писать стеки и очереди,а лабу надо срочно сдать. Проверить, является ли данная строка, состоящая только из...

Правильная скобочная последовательность - C++
Рассмотрим последовательность, состоящую из круглых, квадратных и фигурных скобок. Программа должна определить, является ли данная...

Правильная реализация в цикле - C++
pole=fig; pole=fig; pole=fig; pole=fig; pole=fig; pole=fig; pole=fig; pole=fig; pole=fig; pole=fig;


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

Или воспользуйтесь поиском по форуму:
alsav22
5416 / 4812 / 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     Правильная инициализация ?
Ответ Создать тему
Опции темы

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