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

Проблема с выделением памяти - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.85
Wolf6969
0 / 0 / 0
Регистрация: 07.09.2011
Сообщений: 15
07.09.2011, 23:03     Проблема с выделением памяти #1
Всем привет!
Нужна помощь. Создаю класс и при компиляции возникает ошибка. Не пойму причину. Помогите пожалуйста. Конструктор должен выделять память под двумерный массив, конструктор копий должен соответственно выделить память и скопировать массив поэлементно. Но не получается пока ;(

вот код

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
#include <iostream>
#include  <conio.h>
#include <windows.h>
 
using std::cout;
using std::cin;
 
class Table{
    int size;
    int *table;
public:
    Table(int size){
        int **table = new int *[size];
        for (int i = 0; i < size; i++)
                table[i] = new int [size];
        }
 
    Table(const Table &t0){
        int **table = new int *[t0.size];   //выделение памяти для матрицы
        for (int i = 0; i < t0.size; i++)
                table[i] = new int [t0.size];
 
        for (int i = 0; i < t0.size; ++i)
            for (int j = 0; j < t0.size; ++j)
                table[i][j] = t0.table[i][j];      //строка 25
        }
 
    ~Table(){
        for (int i = 0; i < size; i++)
                delete table[i];                    //строка 30
        delete[] table;
        }
 
    int detA();
 
};
 
 
int main(int argc, char *argv[]){
    cout<<"Hello";
    Table t1(10);
    getch();
return 0;
}
ОШИБКИ:
строка 25 Invalid type argument of 'unary *'
строка 25 Invalid type 'int[int]' for array subscript
строка 30 Type 'int' argument given to delete, expected pointer

Всем кто откликнется огромное спасибо
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Enfernuz
 Аватар для Enfernuz
22 / 22 / 1
Регистрация: 11.04.2011
Сообщений: 67
07.09.2011, 23:18     Проблема с выделением памяти #2
у вас поле-член класса int* table, а в конструкторе вы объявляете локальный указатель int** table. В строке 25 компилятор оперирует с указателем int* table (поле-член класса), а не с локальным указателем int** table.
t0.table[i][j] некорректно по этой же причине (потому что table --- это int*).
Решение: сделать указатель-член класса типа int**, то есть int** table. И инициализацию делать так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Table(int size){
        table = new int* [size];
        for (int i = 0; i < size; i++)
                table[i] = new int [size];
        }
 
    Table(const Table &t0){
        table = new int* [t0.size];   //выделение памяти для матрицы
        for (int i = 0; i < t0.size; i++)
                table[i] = new int [t0.size];
 
        for (int i = 0; i < t0.size; ++i)
            for (int j = 0; j < t0.size; ++j)
                table[i][j] = t0.table[i][j];      //строка 25
        }
В деструкторе код такой:
C++
1
2
3
4
5
~Table(){
        for (int i = 0; i < size; i++)
                delete[] table[i];                    //удаляем массивы int*-ов
                delete[] table;                       //удаляем массив int**-ов
        }
Wolf6969
0 / 0 / 0
Регистрация: 07.09.2011
Сообщений: 15
07.09.2011, 23:24  [ТС]     Проблема с выделением памяти #3
Enfernuz, спасибо. Но все таки не пойму, почему не достаточно просто изменить *int в обьявлении на **int. Зачем менять инициализацию? Просто чтобы проще было?
Enfernuz
 Аватар для Enfernuz
22 / 22 / 1
Регистрация: 11.04.2011
Сообщений: 67
07.09.2011, 23:37     Проблема с выделением памяти #4
В конструкторах вы объявляете локальный указатель типа int**, не имеющий никакого отношения к членам класса, за исключением того, что имеет такое же имя, что и указатель-член класса int* table. Завидев table в теле функции-члена класса, компилятор обратится к полю-члену класса --- указателю int* table.
У класса Table в вашей реализации есть поле --- одномерный массив, и это указатель int* table. Чтобы это был двумерный массив, необходим указатель int**.

Добавлено через 4 минуты
То есть, даже если вы измените int* на int** в public, в конструкторах строчка вида
C++
1
int **table = new int *[size];
будет приводить не к инициализации указателя-члена класса, а к инициализации локального экземпляра указателя типа int** (имеющего смысл только в теле функции и больше нигде).
Wolf6969
0 / 0 / 0
Регистрация: 07.09.2011
Сообщений: 15
08.09.2011, 00:45  [ТС]     Проблема с выделением памяти #5
Я вьехал!!! Спасибо за подробное обьяснение. Без последней фразы не понял бы) Еще раз благодарен.

Добавлено через 21 минуту
К сожалению не все так гладко. При попытке проверить корректность выделения возникла новая трабла.

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
#include <iostream>
#include  <conio.h>
#include <windows.h>
 
using std::cout;
using std::cin;
 
class Table{
    int size;
    int **table;
public:
    Table(int size){
        table = new int* [size];
        for (int i = 0; i < size; i++){
            table[i] = new int [size];
        }
 
        for (int i = 0; i < size; ++i){
            for (int j = 0; j < size; ++j){
                table[i][j]=rand()%10+1;
            }
        }
    }
 
    Table(const Table &t0){
         table = new int* [t0.size];   //выделение памяти для матрицы
         for (int i = 0; i < t0.size; i++){
             table[i] = new int [t0.size];
         }
 
         for (int i = 0; i < t0.size; ++i){
             for (int j = 0; j < t0.size; ++j){
                  table[i][j] = t0.table[i][j];
             }
         }
    }
 
    ~Table(){
        for (int i = 0; i < size; i++){
            delete[] table[i];                 //удаляем массивы int*-ов
        }
        delete[] table;                       //удаляем массив int**-ов
    }
    int detA();
 
    void showtable(){
        for (int i = 0; i < size; ++i){
            for (int j = 0; j < size; ++j){
                cout << table[i][j] << " ";
            }
            cout << "\n"
        }
    }
 
};
 
 
int main(int argc, char *argv[]){
    Table t1(5);
    t1.showtable();
    cout << "Done";
    getch();
return 0;
}
в итоге вижу в консоли только done
Отладка показывает, что в этом месте
C++
1
2
3
4
5
  for (int i = 0; i < size; ++i){
            for (int j = 0; j < size; ++j){
                table[i][j]=rand()%10+1;
            }
        }
с элементами массива -члена класса ничего не происходит, там просто адреса.
тоесть не работает ;(

Добавлено через 39 минут
Ошибку нашел, испарвил.
Yandex
Объявления
08.09.2011, 00:45     Проблема с выделением памяти
Ответ Создать тему
Опции темы

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