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


Автор: Kurt 10.9.2003, 16:31
Обычно я работаю с Delphi, но тут пришлось использовать C++Builder.
Подскажите, пожалуйста, есть ли в C++Builder динамические массивы?
Если можно, приведите простенький пример как с ними работать.
Особенно нужен пример работы с аналогом Дельфового SetLength (если в C++Builder есть аналог такой функции).
Заранее спасибо.

Автор: Vyacheslav 10.9.2003, 16:40
см. STL: vector

Автор: Kurt 10.9.2003, 21:06
Признаю свою непонятливость, но как с вектором работать я не сообразил.
Ладно, а если мне не недо сохранять данные перед изменением размера?
В общем задача в простой форме:
нужно выделить память под массив байтов, размер массива определяется run-time.
Знаю есть API-функции для этого (VirtualAlloc & GlobalAlloc.. кстати, какая разница?).
Но хотелось бы средствами C++...

Автор: RAN 10.9.2003, 21:39
Конечно, C++. new и delete.
int *arr = new int[n]; //выделить n*sizeof(int) байт под массив. Теперь пользуйся arr[0], arr[1], ... arr[n]
................
delete[] arr; //освободить память

Чтоб изменить размер массива делают так: (так делают известные мне реализации STL):
int *arr = new int[n];
......................
{
int *temp = 0; //Объявить временную переменную под новый блок памяти
temp = new int[new_size]; //создать новый массив
if(temp) CopyMemory(temp, arr, n * sizeof(int)); //скопировать содержимое старого массива в новый
delete[] arr; //освободить память, занятую старым массивом
arr = temp; //присвоить указатель на новый массив arr
}
......................
delete[] arr;


Автор: Kurt 10.9.2003, 22:51
Извини, а это n должно быть константой?
Или можно во время работы проги назначать?
Типа:
int n=10;
int *arr = new int[n];
Или?...
Просто в данный момент у меня нет доступа к C++Builder и я не могу проверить...

Автор: mr.DUDA 10.9.2003, 22:54
Цитата
Знаю есть API-функции для этого (VirtualAlloc & GlobalAlloc.. кстати, какая разница?).

Не советовал бы злоупотреблять VirtualAlloc, т.к. память выделяется целыми страницами по 4Кб.

Используй "кучу" (heap), и если не догоняешь "new/delete", но зато знаешь что такое Alloc, пользуйся парой функций "malloc/free" (кстати, оператор "new" в конечном итоге всё равно вызывает функцию malloc).

Цитата
а это n должно быть константой?
Или можно во время работы проги назначать?

Можно ставить значение в run-time.

Автор: RAN 10.9.2003, 22:57
n - не константа.

Автор: Vyacheslav 11.9.2003, 09:23
Уточни тогда вопрос:что ты понимашь под динмическим массивом: массив, созданный динамически, или массив с динамически изменяемой длинной?

В качестве массива байтов можно использовать string
примеры использования

Код

#include <iostream.h>
#include <stl.h>

int main ()
{
 vector<int> years;
 years.push_back (1962);
 years.push_back (1992);
 years.push_back (2001);
 years.push_back (1999);
 sort (years.begin (), years.end ());
 vector<int>::iterator i;
 for (i = years.begin (); i != years.end (); i++)
   cout << *i << endl;
 return 0;
}


Код

#include <iostream.h>
#include <stl.h>

int main ()
{
 vector<char> v1; // Empty vector of characters.
 v1.push_back ('h');
 v1.push_back ('i');
 cout << "v1 = " << v1[0] << v1[1] << endl;
 vector<char> v2 (v1);
 v2[1] = 'o'; // Replace second character.
 cout << "v2 = " << v2[0] << v2[1] << endl;
 cout << "(v1 == v2) = " << (v1 == v2) << endl;
 cout << "(v1 < v2) = " << (v1 < v2) << endl;
 return 0;
}




Автор: Fantasist 11.9.2003, 19:10
Цитата

Чтоб изменить размер массива делают так: (так делают известные мне реализации STL)

{
int *temp = 0; //Объявить временную переменную под новый блок памяти
temp = new int[new_size]; //создать новый массив
if(temp) CopyMemory(temp, arr, n * sizeof(int)); //скопировать содержимое старого массива в новый
delete[] arr; //освободить память, занятую старым массивом
arr = temp; //присвоить указатель на новый массив arr
}



Такие реализации STL выбрасывать надо сразу. Такое поведение допустимо только для valarray, ну и bitset (может еще чего забыл). В других контейнерах должен использоваться operator=, а не CopyMemory.

Автор: RAN 11.9.2003, 19:13
Fantasist, смысл-то не в CopyMemory, а в том что, чтобы увеличить размерность STL создаёт новый массив и копирует в него новый. Для стандартных типов (int и т.д.) копировать можно, это же не классы.

Автор: Nastya 11.9.2003, 20:04
Существует несколько способов динамически работать с массива
1. Используя шаблон классов vector
2. Используя операторы new и delete, при этом подходе ты сам "вручную " пишешь функцию изменения размера массива и на твоей совести ее корректная работа
3. Использовать функции alloc, free, или их WinApi-шные при это ты не только следишь за тем что описанно в п.2, но если речь идет об массиве объектов, то и за корректным вызовом конструкторов и деструкторов.

Наиболее предпочтительный вариант 1. В форуме не раз заходила речь об STL и даже где-то были ссылки на учебники идоки.
Если проблема более конкретная опиши.

Автор: podval 12.9.2003, 07:43
Ребята, обратите внимание на вопрос:
Цитата
Обычно я работаю с Delphi, но тут пришлось использовать C++Builder.


В Дельфи динамические массивы - это особый тип.
Вот что сделано в Билдере (см. help):

Цитата
DynamicArray is the C++Builder analog for the Object Pascal dynamic array type.

Header

sysdyn.h

Description

A Dynamic Array is a resizable collection implemented as an array. C++Builder provides the DynamicArray template as an implementation of Dynamic Arrays. The DynamicArray template uses a binary layout compatible with Delphi's Dynamic Array implementation, enabling you to share DynamicArrays of types compatible with both Delphi and C++Builder using Pascal and C++ code.

Syntax

template <class T> class DELPHIRETURN DynamicArray;



Автор: podval 12.9.2003, 07:45
Вот, кстати, с того же help'a:

C++ DynamicArray example

Код

#include <sysdyn.h>
#include <stdio.h>
#include "dynpas.hpp"

class someobject
{
public:
 someobject()
 {
   printf("someobject::someobject() %p \n", this);
 }
~someobject()
 {
   printf("someobject::~someobject() %p \n", this);
 }

};


void dumpArrayOfString(const DynamicArray<AnsiString>& ds)
{
 for (int i=0; i<ds.Length; i++)
   printf("%s\n", ds[i].c_str());
}

void dump2DArrayOfString(const DynamicArray< DynamicArray<AnsiString> > & ds)

{
 for (int i=0; i<ds.Length; i++)
 {
   for (int j=0; j<ds[i].Length; j++)
     printf("%s ", ds[i][j].c_str());
   printf("\n");
 }
}

int main(void)
{
 DynamicArray<AnsiString> oneD;
 printf("Dimension: %d \n", oneD.DimCount());
 fillArrayOfString(oneD);
 dumpArrayOfString(oneD);

 DynamicArray<DynamicArray<AnsiString> > twoD;
 printf("Dimension: %d \n", twoD.DimCount());
 fill2DArrayOfString(twoD);
 dump2DArrayOfString(twoD);

 return 0;

}

© Borland

Автор: DENNN 12.9.2003, 11:57
Цитата
смысл-то не в CopyMemory, а в том что, чтобы увеличить размерность STL создаёт новый массив и копирует в него новый.

Вот и надо было так написать smile.gif

Автор: B2_Russia 15.9.2003, 12:12
Ничего не читал кроме вопроса топика, и давно не писал ничего ни на Делфях ни на Билдере, но по-моему очень удобно использовать CList гы Хотя уже не помню что это такое...

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