Динамический массив???
От: Lozovoy  
Дата: 24.09.01 20:04
Оценка:
Подскажите плз.Как создать динамический массив ?

Заранее спасибо.
Re: Динамический массив???
От: Андрей Тарасевич Беларусь  
Дата: 24.09.01 20:14
Оценка:
Здравствуйте Lozovoy, вы писали:

L>Подскажите плз.Как создать динамический массив ?


Что такое "динамический массив" ???

Если речь идет о массиве, размер которого неизвестен на стадии компиляции, то такие массивы можно разделить на два класса:

1) Массивы фиксированного размера. Размер неизвестен на стадии компиляции. Используется механизм 'new[]/delete[]'.

unsigned nSize = ...;

int* iArray = new int[nSize];
...
delete[] iArray;


2) Массивы переменного размера. Используется 'std::vector'.

Можно и 1) реализовывать через 'std::vector' ценой некоторых дополнительных накладных расходов.

Best regards,
Андрей Тарасевич,
Brainbench C and C++ Programming MVP
Best regards,
Андрей Тарасевич
Re: Динамический массив???
От: Igor Soukhov  
Дата: 24.09.01 20:33
Оценка:
Здравствуйте Lozovoy, вы писали:

L>Подскажите плз.Как создать динамический массив ?


L>Заранее спасибо.


Если тебе нужен ИМЕННО массив (а он тебе не нужен, почему —
читай ниже) — то вот так:

int sar[1979];//это такой грустный массив на стеке ...
              //если он глобальный - то еще хуже ...
              //хотя вряд-ли он глобальный ...
              //ибо если он был бы глобальным - я бы назвал его
              //g_ar ...
              //я несколько отвлекся =)     

int *par = new int[1979];//выделяем динамически память под массив

par[1] = 1;//делаем вид что работает с массивом ...
par[9] = 2;//хотя par - это указатель - но вроде как сам кастится
par[7] = 7;//к типу массива ... ну да ладно
par[9] = 9;//

delete[] par;//освобождаем память ... куда нам столько ее ...

par = new int[9];//выделяем динамически память под массив поменьше ...

par[1] = 1;//делаем вид что работает с массивом ...
par[9] = 2;//вот тут выход за пределы массива ... но в дебаге наверняка будет работать ...
par[7] = 7;//
par[9] = 9;//вот тут выход за пределы массива ... но в дебаге наверняка будет работать ...

//делаем еще миллион интересных вещей с этим массивом ...

//delete[] par;//забываем освобождить память 
delete par;//делаем ошибку ... (надо было delete[] par)...


Все вот так сложно ... но слава б#гу можно STL предоставляет нам
класс-контейнер vector .... с ним код гораздо проще:

#include <vector>//да - приходится подключать заголовочный файл ...
using std::vector;//а кому щас легко ? 

vector<int> vi(1979);

vi[1] = 1;
vi[9] = 2;
vi[7] = 7;
vi[9] = 9;

vi.resize(9);//уменьшаем размер вектора ...

vi[1] = 1;
vi[9] = 2;//вот тут выход за пределы вектора ... но в дебаге наверняка будет работать ...
vi[7] = 7;
vi[9] = 9;//вот тут выход за пределы вектора ... но в дебаге наверняка будет работать ...

//и все ... память сама освободиться и вычистится десткуртором славного класса vector ...
* thriving in a production environment *
Re: Динамический массив???
От: Alex  
Дата: 25.09.01 17:55
Оценка:
Здравствуйте Lozovoy, вы писали:

L>Подскажите плз.Как создать динамический массив ?


L>Заранее спасибо.


1.----------------
Есть ещё один способ, не перечисленный выше — это конструкция из malloc/realloc/free, например:

struct TMyStruct
{
int ID;
int Number;
};

TMyStruct* Array=0;
int ArraySize=5;

//создаём массив структур
//malloc выделит необходимое количество динамической памяти, надо помнить что она не инициализирует её!!
Array=(TMyStruct*)malloc(sizeof(TMyStruct)*ArraySize);

//обращение к массиву
Array[0]=Array[2];
Array[3].ID=7;

//изменения размера массива
//при этом, все данные в массиве сохраняются (т.е. первые пять элементов останутся не изменными)
ArraySize=20;
Array=(TMyStruct*)realloc(Array, sizeof(TMyStruct)*ArraySize);

//какие то операции с массивом

//удаление массива
free(Array);

2.------------------
//вот в принципе и всё, хотя функцией realloc можно заменить функции free и malloc, выглядит это так (пример 2):

TMyStruct* Array=0;
int ArraySize=5;

//создаём массив структур
Array=(TMyStruct*)realloc(Array, sizeof(TMyStruct)*ArraySize);

//изменения размера массива
ArraySize=20;
Array=(TMyStruct*)realloc(Array, sizeof(TMyStruct)*ArraySize);

//удаление массива
ArraySize=0;
Array=(TMyStruct*)realloc(Array, sizeof(TMyStruct)*ArraySize);

Может пригодится.
С уважением!
Алексей.
Re: Динамический массив???
От: YuriS Германия www.yuris.de
Дата: 25.09.01 18:13
Оценка:
Здравствуйте Lozovoy, вы писали:

L>Подскажите плз.Как создать динамический массив ?


Попробуй CArray очень прост в использовании.

Удачи.
Re[2]: Динамический массив???
От: Tigor Россия  
Дата: 25.09.01 18:37
Оценка:
Здравствуйте Igor Soukhov, вы писали:

IS>Здравствуйте Lozovoy, вы писали:



IS>//delete[] par;//забываем освобождить память

IS>delete par;//делаем ошибку ... (надо было delete[] par)...

Мне казалось, что это не ошибка. По крайней мере все работает, утечек памяти не возникает. И вроде бы я даже где-то читал, что можно не указывать эти скобки после delete, хотя этой книги сейчас под рукой нет и проверить не могу.
К сожалению, в действительности все выглядит иначе, чем на самом деле.
Re[3]: Динамический массив???
От: Igor Soukhov  
Дата: 25.09.01 18:41
Оценка:
Здравствуйте Tigor, вы писали:

T>Здравствуйте Igor Soukhov, вы писали:


IS>>//delete[] par;//забываем освобождить память

IS>>delete par;//делаем ошибку ... (надо было delete[] par)...

T>Мне казалось, что это не ошибка. По крайней мере все работает, утечек памяти не возникает. И вроде бы я даже где-то читал, что можно не указывать эти скобки после delete, хотя этой книги сейчас под рукой нет и проверить не могу.

А книга-то хорошая ? Ну там твердая обложка, большой шрифт, хорошая бумага ?
* thriving in a production environment *
Re[3]: Динамический массив???
От: Alex  
Дата: 25.09.01 18:58
Оценка:
На самом деле можно указывать, а можно и не указывать.
Компилятор же тоже не глупый, он же видит что скрывается под именем переменной.
Re[4]: Динамический массив???
От: Tigor Россия  
Дата: 25.09.01 18:59
Оценка:
Здравствуйте Igor Soukhov, вы писали:

IS>А книга-то хорошая ? Ну там твердая обложка, большой шрифт, хорошая бумага ?


Да вроде хорошая :) Я потом в другой прочел, что надо эти скобки ставить и очень испугался, что все жизнь делал не правильно. :-)
Даже пререпатчил какой-то проектик свой.... А потом опять нашел ту книгу (Беризины — авторы вроде) и там точно было написано, что можно не указывать...

Visual C++ 6.0 не замечает утечек памяти, если их не указывать, поэтому я решил, что все нормально и они не обязательны.
К сожалению, в действительности все выглядит иначе, чем на самом деле.
Re[4]: Динамический массив???
От: IT Россия linq2db.com
Дата: 25.09.01 19:05
Оценка:
Здравствуйте Alex, вы писали:

A>На самом деле можно указывать, а можно и не указывать.

A>Компилятор же тоже не глупый, он же видит что скрывается под именем переменной.

void f(int *n)
{
    delete n; // и как ему тут понять, что там скрывается?
}
void f2()
{
    int *n1 = new int;
    int *n2 = new int[10];
    f(n1);
    f(n2);
}
Если нам не помогут, то мы тоже никого не пощадим.
Re[5]: Динамический массив???
От: Alex  
Дата: 25.09.01 19:09
Оценка:
Здравствуйте IT, вы писали:

IT>Здравствуйте Alex, вы писали:


A>>На самом деле можно указывать, а можно и не указывать.

A>>Компилятор же тоже не глупый, он же видит что скрывается под именем переменной.

IT>
IT>void f(int *n)
IT>{
IT>    delete n; // и как ему тут понять, что там скрывается?
IT>}
IT>void f2()
IT>{
IT>    int *n1 = new int;
IT>    int *n2 = new int[10];
IT>    f(n1);
IT>    f(n2);
IT>}
IT>


В любом случае у нас есть массив, только n1 — указатель на массив из одного элемента, а n2 — указатель на массив из двух элементов. Вот и вся разница.
Re[4]: Динамический массив???
От: Андрей Тарасевич Беларусь  
Дата: 25.09.01 19:27
Оценка:
Здравствуйте Alex, вы писали:

A>На самом деле можно указывать, а можно и не указывать.

A>Компилятор же тоже не глупый, он же видит что скрывается под именем переменной.

Ну так давайте тогда вообще выделять память через 'new[]', а освобождать через 'free()'. Компилятор же тоже не глупый...

Best regards,
Андрей Тарасевич,
Brainbench C and C++ Programming MVP
Best regards,
Андрей Тарасевич
Re[6]: Динамический массив???
От: Tigor Россия  
Дата: 25.09.01 19:27
Оценка:
Вот маленький тестовый код (Visual C++ 6.0):

class Test
{
public:
Test(void)
{
printf("Constructor\n");
}

~Test(void)
{
printf("Destructor\n");
}
};

int main(int argc, char* argv[])
{
Test* pTest = new Test[3];

delete pTest; // Ошибка!!!! Debug Assertion Failed
// после вызова деструктора первого объекта

char* pChar = new char [3];

delete pChar; Никаких ошибок во время выполнения,
хотя утечка памяти, наверно, возникает.

return 0;
}

Как заставить вижуал показать утечку памяти? Если я убираю delete pChar, он все равно ее не пишет.
К сожалению, в действительности все выглядит иначе, чем на самом деле.
Re[6]: Динамический массив???
От: Андрей Тарасевич Беларусь  
Дата: 25.09.01 19:30
Оценка:
Здравствуйте Alex, вы писали:

A>>>На самом деле можно указывать, а можно и не указывать.

A>>>Компилятор же тоже не глупый, он же видит что скрывается под именем переменной.

IT>>
IT>>void f(int *n)
IT>>{
IT>>    delete n; // и как ему тут понять, что там скрывается?
IT>>}
IT>>void f2()
IT>>{
IT>>    int *n1 = new int;
IT>>    int *n2 = new int[10];
IT>>    f(n1);
IT>>    f(n2);
IT>>}
IT>>


A>В любом случае у нас есть массив, только n1 — указатель на массив из одного элемента, а n2 — указатель на массив из двух элементов. Вот и вся разница.


Такие компиляторы — в сад. Выделять память для одного 'int' как для массива 'int[1]' — расточительно.

Best regards,
Андрей Тарасевич,
Brainbench C and C++ Programming MVP
Best regards,
Андрей Тарасевич
Re[5]: Динамический массив???
От: Alex  
Дата: 25.09.01 19:32
Оценка:
Здравствуйте Андрей Тарасевич, вы писали:

:))))))))))))))))))
Re[7]: Динамический массив???
От: Андрей Тарасевич Беларусь  
Дата: 25.09.01 19:35
Оценка:
Здравствуйте Tigor, вы писали:

T>Вот маленький тестовый код (Visual C++ 6.0):


T>class Test

T>{
T> public:
T> Test(void)
T> {
T> printf("Constructor\n");
T> }

T> ~Test(void)

T> {
T> printf("Destructor\n");
T> }
T>};

T>int main(int argc, char* argv[])

T>{
T> Test* pTest = new Test[3];

T> delete pTest; // Ошибка!!!! Debug Assertion Failed

T> // после вызова деструктора первого объекта

T> char* pChar = new char [3];


T> delete pChar; Никаких ошибок во время выполнения,

T> хотя утечка памяти, наверно, возникает.

T> return 0;

T>}

T>Как заставить вижуал показать утечку памяти? Если я убираю delete pChar, он все равно ее не пишет.


Для того, чтобы VC показывал утечку памяти, над сделать

#define new DEBUG_NEW


и линковаться с MFC.

В любом случае, с чего ты взял, что будет утечка памяти из-за 'delete' вместо 'delete[]' ? Скажу тебе по секрету, что в данном конкретном случае никакой утечки памяти не будет.

В С++ смешивание 'delete' с 'delete[]' приводит к неопределенному поведению. Утечка памяти — лишь пример того, что может произойти.

Best regards,
Андрей Тарасевич,
Brainbench C and C++ Programming MVP
Best regards,
Андрей Тарасевич
Re[6]: Динамический массив???
От: IT Россия linq2db.com
Дата: 25.09.01 19:36
Оценка:
Здравствуйте Alex, вы писали:

A>В любом случае у нас есть массив, только n1 — указатель на массив из одного элемента, а n2 — указатель на массив из двух элементов. Вот и вся разница.


Пример не удачный с интами, а если будут объекты, то приплыли.
Если нам не помогут, то мы тоже никого не пощадим.
Re[7]: Динамический массив???
От: IT Россия linq2db.com
Дата: 25.09.01 19:37
Оценка:
Здравствуйте Андрей Тарасевич, вы писали:

АТ>Такие компиляторы — в сад. Выделять память для одного 'int' как для массива 'int[1]' — расточительно.


При чём тут комриляторы? В сад — программистов ;)
Если нам не помогут, то мы тоже никого не пощадим.
Re[7]: Динамический массив???
От: Alex  
Дата: 25.09.01 19:43
Оценка:
Здравствуйте Андрей Тарасевич, вы писали:

A>>В любом случае у нас есть массив, только n1 — указатель на массив из одного элемента, а n2 — указатель на массив из двух элементов. Вот и вся разница.


АТ>Такие компиляторы — в сад. Выделять память для одного 'int' как для массива 'int[1]' — расточительно.


Эти две строки:

int *n1 = new int;
int *n1 = new int[1];

работают аналогично
Re[7]: Динамический массив???
От: Alex  
Дата: 25.09.01 19:58
Оценка:
1.--------------------------------------------
//C++

int* p1=new int;

//то же на ассемблере

push 4
call @$bnew$qui
pop ecx
mov dword ptr [ebp-12],eax

2.--------------------------------------------
//C++
int* p2=new int[1];

//то же на ассемблере
push 4
call @$bnwa$qui
pop ecx
mov dword ptr [ebp-16],eax


Как вижно, компилятор делает один и тот же код. Что и требовалось доказать.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.