Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Про указатели


Автор: seravr 26.2.2009, 13:06
Товарищи, подскажите пожалуйста.
В хидере класса я объявляю указатель на массив указателей, типа вот так:
int** data;

или надо вот так:

int* data[];
Но в этом случае компилятор ругается, что надо определить размер массива, тогда я пишу так:

int* data[size];
в этом случае выдает варнинг

Подскажите пожалуйста как правильно вообще это организовать

Вот пример кода:

class My
{
public:
    My(int SIZE=100);
    ~My();

private:
    size;// размер массива указателей
    int* data[size];// массив указателей
    // или надо int** data???
};

А в файле .cpp в конструкторе мне надо инициализировать массив указателей нулями, т.е. NULL.
Я не пойму как это сделать, толи в .cpp явно инициализировать массив указателей(его размер и на что они в данный момент указывают,т.е. NULL), то ли просто писать в конструкторе что-то типа :

... 

My::My(int SIZE)
    :size(SIZE)
{
    for(int i=0;i<size;i++)
        data[i]=NULL;
}

...

Дело в том, что если я так пишу, то операционка выдает что-то типа: попытка записи в защищенную память, и аварийно завершает программу.

Прошу пожалуйста помочь, как правильно мне это организовать

Спасибо всем.
Очень ценю мнение каждого.

Автор: mes 26.2.2009, 13:14
Цитата(seravr @  26.2.2009,  12:06 Найти цитируемый пост)

Дело в том, что если я так пишу, то операционка выдает что-то типа: попытка записи в защищенную память, и аварийно завершает программу.

Указатель объявили, а куда он должен указывать не показали...


Автор: seravr 26.2.2009, 13:19
я их инициализирую нулями 
 data[i]=NULL;

Автор: mes 26.2.2009, 13:21
Цитата(seravr @  26.2.2009,  12:06 Найти цитируемый пост)

А в файле .cpp в конструкторе мне надо инициализировать массив указателей нулями, т.е. NULL.

data = NULL;

Цитата(seravr @  26.2.2009,  12:06 Найти цитируемый пост)

Подскажите пожалуйста как правильно вообще это организовать

Ваш вопрос представляет кучу вариантов для толкования... И ответить на него кратко, не зная основной задачи (*) не получится.

(*) для чего вобще Вы собираетесь использовать указ. на массив указ.?   двухмерный массив ?

Добавлено @ 13:23
Цитата(seravr @  26.2.2009,  12:19 Найти цитируемый пост)
я их инициализирую нулями 
 data[i]=NULL; 

как Вы можете инициализировать "их", если не знаете где "они" расположены ?! 
Вы сами написали:
Цитата(seravr @  26.2.2009,  12:06 Найти цитируемый пост)
указатель на массив указателей

так что , чтоб работать с массивом_указатeлей, нужно вначале проинициализировать указатель_на_массив_указателей.

Автор: Dem_max 26.2.2009, 13:25
А какую область памяти ты инициализируешь нулями ? ты под указатели не выделил память вот тебе и ошибка.

Автор: seravr 26.2.2009, 13:29
вообщем, это нужно для создания простой базы данных, в ней имеется указатель на объекты(объектов много, для простоты пусть они будут типа int )

Автор: C/L 26.2.2009, 13:30
Как я понял size здесь не константа, заранее не известен, поэтому

class My
{
public:
    My(int SIZE=100);
    ~My();

private:
    size;// размер массива указателей
    int** data;// массив указателей
    // или надо int** data???
};


My::My(int SIZE)
    :size(SIZE)
{
    data = new *int[size];
    for(int i=0;i<size;i++)
        data[i]=NULL;
}

My::~My()
{
    ......
    delete data[];
}

Автор: mes 26.2.2009, 13:35
Цитата(seravr @  26.2.2009,  12:29 Найти цитируемый пост)
в ней имеется указатель на объекты(

Мне кажется Вы злоупотребляете словом "указатель" - и из за этого проблемы с пониманием того чего хотите получить.

Вам нужен линейный контейнер для хранения объектов  ?
1. std::vector<T> v; - рекомендуемая альтернатива динамическому си-массиву.
2. T mas[size]; - статический массив
3. T* mas; mas = new Т[size]; - динамический массив, скрытый за указателем.
где Т - Ваш тип


Автор: seravr 26.2.2009, 13:42
спасибо Всем, начал понимать.

А могу я сделатьтак:

 class My
{
public:
    My(int SIZE=100);
    ~My();

private:
    size;// размер массива указателей
  [b]  int** ptrData;// указатель на массив указателей
   int* data[];// собственно, сам массив указателей

// здесь нужно писать data[] или надо data[размер]???[/B]
};


My::My(int SIZE)
    :size(SIZE)
{
    data = new *int[size];
    for(int i=0;i<size;i++)
        data[i]=NULL;

 ptrData=data[0];
}

My::~My()
{
    ......
    delete data[];
}

Добавлено @ 13:47
ребята, я что то запутался, если мы пишем 

int** data

это ведь указатель на массив указателей
Тогда почему мы инициализируем его типом *int[] так в конструкторе:
data = new *int[size];


Автор: C/L 26.2.2009, 13:49
В С++ массив и указатель одно и то же. Массив = указателю на первый элемент

Автор: zim22 26.2.2009, 13:52
Цитата(seravr @  26.2.2009,  13:42 Найти цитируемый пост)
data = new *int[size];

надо так:
Код

data = new int*[size];

Автор: Dmi3ev 26.2.2009, 14:04
возьмем для примера массив 4х3, чтобы не было квадратика, а то не поймешь...
Код

int n=4;
int m=3;

int **a;//просто создали указатель

a=new int*[m];//можно сказать (для понимания), что выделили память под столбцы


опять же для понимания, сейчас у нас вот так
  0    1    2
[...] [...] [...]
те массив у нас уже есть, а нам нужен массив массивов, те
     0    1    2
0 [...] [...] [...]
1 [...] [...] [...]
2 [...] [...] [...]
3 [...] [...] [...]
т.е. в кадый из элементов первого массва запихнуть по массиву
  0                1            2
[массив] [массив] [массив]
это делается вот так
Код

for (int i=0; i<m; i++)
 a[i]=new int[n];

все это только для объяснения, чтобы человек понял... что ваще происходит

Автор: seravr 26.2.2009, 14:05
Друзья, как я понял, нужно в хидере объявить int** data;
а в файле .cpp нужно писать data = new int*[size];


т.е. получается что int** data; и int* data[]; -это одно и тоже???

Автор: Carnivore 26.2.2009, 14:05
Цитата(C/L @  26.2.2009,  13:49 Найти цитируемый пост)
В С++ массив и указатель одно и то же

А вот и нет  smile 

Автор: seravr 26.2.2009, 14:07
Dmi3ev, преогромнейшее спасибо Вам, разобрался

Автор: C/L 26.2.2009, 14:13
Цитата(Carnivore @  26.2.2009,  16:05 Найти цитируемый пост)
Цитата(C/L @  26.2.2009,  13:49 )
В С++ массив и указатель одно и то же


А вот и нет    

Ну может и не совсем. Я имел ввиду синтаксически
Код

int* a = new int[3];
*a = 3; // что так
a[0] = 3; //что так

Автор: TiKKi 26.2.2009, 14:22
Массив есть массив, а его имя - это просто указатель на его первый элемент. Указатель и массив это совсем не одно и тоже!

Автор: C/L 26.2.2009, 14:31
Цитата(TiKKi @  26.2.2009,  16:22 Найти цитируемый пост)
это просто указатель на его первый элемент

ну совсем не просто и не совсем только первый
Код

int* a = new int[3];
*a = 1;
a++;
*a = 2;
a++;
*a = 3;

Автор: seravr 26.2.2009, 14:52
Друзья, спасибо Всем

Добавлено через 2 минуты и 26 секунд
Цитата(C/L @ 26.2.2009,  13:30)
    ......
    delete data[];

только надо delete [] data;

Автор: TiKKi 26.2.2009, 14:56
Цитата(C/L @ 26.2.2009,  14:31)
Цитата(TiKKi @  26.2.2009,  16:22 Найти цитируемый пост)
это просто указатель на его первый элемент

ну совсем не просто и не совсем только первый
Код

int* a = new int[3];
*a = 1;
a++;
*a = 2;
a++;
*a = 3;

Вы это к чему?
Код

int a[10]; // массив
int* b = new int[10]; // указатель
// sizeof( a ) != sizeof( b )  

Его имя (массива) - это просто указатель на его первый элемент.

Автор: Dmi3ev 26.2.2009, 14:58
Цитата

В С++ массив и указатель одно и то же. Массив = указателю на первый элемент

Одно и то же в С++ называется одинаково... Массив=Массив, Указатель=Указатель...
Цитата

ну совсем не просто и не совсем только первый

а это уже твое дело, куда его заставить указывать, но сначала он указывает элемент с индексом (0) (0)... А дальше дело за тобой, у тебя вон как ловко получается  smile 
Цитата

int* a = new int[3];
*a = 1;
a++;
*a = 2;
a++;
*a = 3;


Автор: seravr 26.2.2009, 15:04
Цитата(C/L @ 26.2.2009,  14:13)
Цитата(Carnivore @  26.2.2009,  16:05 Найти цитируемый пост)
Цитата(C/L @  26.2.2009,  13:49 )
В С++ массив и указатель одно и то же


А вот и нет    

Ну может и не совсем. Я имел ввиду синтаксически
Код

int* a = new int[3];
*a = 3; // что так
a[0] = 3; //что так

добавлю:

можно еще и так:

0[a] = 3; 
1[a] = 2; 
.
.
.
n[a] = 7; 

Автор: zim22 26.2.2009, 15:25
Цитата(seravr @  26.2.2009,  15:04 Найти цитируемый пост)
можно еще и так:

можно, но не нужно.

Автор: seravr 26.2.2009, 15:26
Цитата(Dmi3ev @ 26.2.2009,  14:04)
возьмем для примера массив 4х3, чтобы не было квадратика, а то не поймешь...
Код

int n=4;
int m=3;

int **a;//просто создали указатель

a=new int*[m];//можно сказать (для понимания), что выделили память под столбцы



скажите пожалуйста, в этой строке int **a имеется ввиду (int *) *a
т.е. указатель на тип int* ? 

Автор: kosmonaFFFt 26.2.2009, 15:55
ага, указатель на (указатель на инт)

Автор: Dmi3ev 26.2.2009, 15:59
не знаю как объяснить, может это поможет, постарался показать, что можно и выделить память, а можно и ...
Код

int main()
{
    const int n=4;
    const int m=3;
    
    int *a;
    a=new int[n];

    int *b;
    b=new int[n];

    int *c;
    c=new int[n];
    
    for (int i=0; i<n; i++)
    {
        a[i]=1;
        b[i]=2;
        c[i]=3;
    }

    int **myarray;
    myarray=new int*[m];
    
    myarray[0]=a;
    myarray[1]=b;
    myarray[2]=c;
    
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<m; j++)
        {
         cout<<*(*(myarray+j)+i)<<"; ";
        }
        cout<<endl;
    }

    system("pause");
    return 0;
}


Добавлено @ 16:00
seravr, попробуй посмотреть эту прогу, должно начать доходить, что такое указатели...

Автор: seravr 26.2.2009, 16:06
Dmi3ev, очень благодарен, спасибо большое

Автор: Dmi3ev 26.2.2009, 16:09
опечаточка была в проге, теперь все ок  smile 

Автор: pan2004 26.2.2009, 17:19
к new неплохо бы и delete добавить:
Код

int main()
{
 ...
 // Так как вся выделенная память доступна через myarray удаляем только его
 delete [] myarray[0]; // аналогично delete a;
 delete [] myarray[1];
 delete [] myarray[2];
 //теперь можно и 
 delete [] myarray;
}

Автор: C/L 26.2.2009, 18:17
Признаю не прав. Указатель и массив не одно и тоже. Правильнее сказать что во многих случаях массив можно использовать как указатель а указатель как массив.

Автор: seravr 26.2.2009, 23:36
Друзья, Спасибо Всем огромное, тему можно закрыть, разобрался, еще раз спасибо Всем

Автор: Dmi3ev 27.2.2009, 00:04
 smile 
Цитата

Друзья, Спасибо Всем огромное, тему можно закрыть, разобрался, еще раз спасибо Всем 

ну так закрывай...

Автор: seravr 27.2.2009, 09:56
закрываю

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)