Здравствуйте 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 ...
Здравствуйте 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):
Здравствуйте Igor Soukhov, вы писали:
IS>Здравствуйте Lozovoy, вы писали:
IS>//delete[] par;//забываем освобождить память IS>delete par;//делаем ошибку ... (надо было delete[] par)...
Мне казалось, что это не ошибка. По крайней мере все работает, утечек памяти не возникает. И вроде бы я даже где-то читал, что можно не указывать эти скобки после delete, хотя этой книги сейчас под рукой нет и проверить не могу.
К сожалению, в действительности все выглядит иначе, чем на самом деле.
Здравствуйте Tigor, вы писали:
T>Здравствуйте Igor Soukhov, вы писали:
IS>>//delete[] par;//забываем освобождить память IS>>delete par;//делаем ошибку ... (надо было delete[] par)...
T>Мне казалось, что это не ошибка. По крайней мере все работает, утечек памяти не возникает. И вроде бы я даже где-то читал, что можно не указывать эти скобки после delete, хотя этой книги сейчас под рукой нет и проверить не могу.
А книга-то хорошая ? Ну там твердая обложка, большой шрифт, хорошая бумага ?
Здравствуйте Igor Soukhov, вы писали:
IS>А книга-то хорошая ? Ну там твердая обложка, большой шрифт, хорошая бумага ?
Да вроде хорошая :) Я потом в другой прочел, что надо эти скобки ставить и очень испугался, что все жизнь делал не правильно. :-)
Даже пререпатчил какой-то проектик свой.... А потом опять нашел ту книгу (Беризины — авторы вроде) и там точно было написано, что можно не указывать...
Visual C++ 6.0 не замечает утечек памяти, если их не указывать, поэтому я решил, что все нормально и они не обязательны.
К сожалению, в действительности все выглядит иначе, чем на самом деле.
Здравствуйте Alex, вы писали:
A>На самом деле можно указывать, а можно и не указывать. A>Компилятор же тоже не глупый, он же видит что скрывается под именем переменной.
void f(int *n)
{
delete n; // и как ему тут понять, что там скрывается?
}
void f2()
{
int *n1 = new int;
int *n2 = new int[10];
f(n1);
f(n2);
}
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте 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 — указатель на массив из двух элементов. Вот и вся разница.
Здравствуйте Alex, вы писали:
A>На самом деле можно указывать, а можно и не указывать. A>Компилятор же тоже не глупый, он же видит что скрывается под именем переменной.
Ну так давайте тогда вообще выделять память через 'new[]', а освобождать через 'free()'. Компилятор же тоже не глупый...
Best regards,
Андрей Тарасевич,
Brainbench C and C++ Programming MVP
Здравствуйте 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
Здравствуйте 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
Здравствуйте Alex, вы писали:
A>В любом случае у нас есть массив, только n1 — указатель на массив из одного элемента, а n2 — указатель на массив из двух элементов. Вот и вся разница.
Пример не удачный с интами, а если будут объекты, то приплыли.
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте Андрей Тарасевич, вы писали:
A>>В любом случае у нас есть массив, только n1 — указатель на массив из одного элемента, а n2 — указатель на массив из двух элементов. Вот и вся разница.
АТ>Такие компиляторы — в сад. Выделять память для одного 'int' как для массива 'int[1]' — расточительно.