Массив в динамической памяти
От: small_cat Россия  
Дата: 18.05.06 04:41
Оценка:
Доброго времени суток.

Пытаюсь сделать следующее:


struct TStruct
{
//
};

const int N = 1000000;
typedef TStruct TStructArray[N];

//и дальше
TStructArray* arr = new TStructArray;


Ошибка C2440, (не может TStruct* привести к TStructArray(*))

Что я делаю не так?
Спасибо.
- Простите, профессор, не пса, а когда он уже был человеком.
— То-есть он говорил? Это еще не значит быть человеком. (с) Булгаков
Re: Массив в динамической памяти
От: Draqon  
Дата: 18.05.06 05:11
Оценка:
Здравствуйте, small_cat, Вы писали:

_>Что я делаю не так?


Советую глянуть в сторону std::vector<TStruct>.
Re: Массив в динамической памяти
От: Вадим Никулин Россия Здесь
Дата: 18.05.06 05:16
Оценка:
Здравствуйте, small_cat, Вы писали:

Нужно так:

TStructArray arr = new TStructArray;


TStructArray — это указатель на TStruct, а у тебя было указатель на указатель на TStruct.
Re: Массив в динамической памяти
От: rg45 СССР  
Дата: 18.05.06 05:45
Оценка: 30 (4)
"small_cat" <3877@users.rsdn.ru> wrote in message news:1902996@news.rsdn.ru...
> Доброго времени суток.
>
> Пытаюсь сделать следующее:
>
>
>
> struct TStruct
> {
> //
> };
> 
> const int N = 1000000;
> typedef TStruct TStructArray[N];
> 
> //и дальше
> TStructArray* arr = new TStructArray;
>

>
> Ошибка C2440, (не может TStruct* привести к TStructArray(*))
>
> Что я делаю не так?
> Спасибо.

Правильно так:
TStruct* arr = new TStructArray;


Выражение new TStructArray эквивалентно выражению new TStruct[N]. Т.е. вданном случе вместо operator newвызывается operator new[]. Убедиться в этом можно так:
void* operator new[](std::size_t n)
{
  std::cout << "new[]" << std::endl;
  return 0;
}
int main()
{
  struct TStruct{};
  const int N = 1000000;
  typedef TStruct TStructArray[N];
  TStruct* arr = new TStructArray; //На экран выводится "new[]"
}
Posted via RSDN NNTP Server 2.0
--
Не можешь достичь желаемого — пожелай достигнутого.
Re: Массив в динамической памяти
От: Анатолий Широков СССР  
Дата: 18.05.06 05:46
Оценка:
TStructArray* arr = new TStructArray[N];
Re: А это чего у нас такое будет?
От: c-smile Канада http://terrainformatica.com
Дата: 18.05.06 06:02
Оценка:
Здравствуйте, small_cat, Вы писали:

_>
_>struct TStruct
_>{
_>//
_>};

_>const int N = 1000000;
_>typedef TStruct TStructArray[N];

_>


На всякий случай:

typedef type-declaration synonym;
Re[2]: А это чего у нас такое будет?
От: rg45 СССР  
Дата: 18.05.06 06:14
Оценка: 27 (2)
"c-smile" <13953@users.rsdn.ru> wrote in message news:1903096@news.rsdn.ru...
> Здравствуйте, small_cat, Вы писали:
>
> _>
> _>struct TStruct
> _>{
> _>//
> _>};
> 
> _>const int N = 1000000;
> _>typedef TStruct TStructArray[N];
> 
> _>

>
> На всякий случай:
>
> typedef type-declaration synonym;

В этом плане у него все правильно:
TStruct tstruct_array[N];                    //объявление массива 
typedef TStruct TStructArray[N];       //добавляем typedef и получаем объявление типа-массива  
//typedef TStructArray[N] TStruct;    //такая конструкция - это ошибка
Posted via RSDN NNTP Server 2.0
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[3]: А это чего у нас такое будет?
От: c-smile Канада http://terrainformatica.com
Дата: 18.05.06 06:35
Оценка: :))
Здравствуйте, rg45, Вы писали:

R>
R>typedef TStruct TStructArray[N];       //добавляем typedef и получаем объявление типа-массива  
R>


Эх, велик и приплюснут сишный язык.

Ну на кой оно так сделано?

(спасибо за разъяснение, сразу не въехал)
Re[4]: А это чего у нас такое будет?
От: rg45 СССР  
Дата: 18.05.06 06:44
Оценка:
"c-smile" <13953@users.rsdn.ru> wrote in message news:1903148@news.rsdn.ru...
> Здравствуйте, rg45, Вы писали:
>
> R>
> R>typedef TStruct TStructArray[N];       //добавляем typedef и получаем объявление типа-массива  
> R>

>
> Эх, велик и приплюснут сишный язык.
>
> Ну на кой оно так сделано?
>

На мой взгляд достаточно логично и удобно: если взять любое объявление переменной, функции или массива и добавить к нему typedef, то получится объявление типа.
Posted via RSDN NNTP Server 2.0
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[5]: А это чего у нас такое будет?
От: Кодёнок  
Дата: 18.05.06 07:08
Оценка:
Здравствуйте, rg45, Вы писали:

R>На мой взгляд достаточно логично и удобно: если взять любое объявление переменной, функции или массива и добавить к нему typedef, то получится объявление типа.


А с какой стати массив объявляется как char G[12], а не как char[12] G?
Re[6]: А это чего у нас такое будет?
От: rg45 СССР  
Дата: 18.05.06 07:22
Оценка:
" Кодёнок " <16798@users.rsdn.ru> wrote in message news:1903220@news.rsdn.ru...
> Здравствуйте, rg45, Вы писали:
>
> R>На мой взгляд достаточно логично и удобно: если взять любое объявление переменной, функции или массива и добавить к нему typedef, то получится объявление типа.
>
> А с какой стати массив объявляется как char G[12], а не как char[12] G?

Ну тут я затрудняюсь ответить, таков уж синтаксис. Если рассуждать в таком ключе, то можно спросить: "почему объявление функции выглядит как char g(int), а не как char(int) g ?". Кроме того конструкции подобные char[12] вполне законны в тех местах, где идентификатор принято опускать, например:
 
template<typename T> class Foo;
template<> class Foo<char[12]> {/*...*/};
Posted via RSDN NNTP Server 2.0
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[7]: А это чего у нас такое будет?
От: Кодёнок  
Дата: 18.05.06 07:38
Оценка:
Здравствуйте, rg45, Вы писали:

>> А с какой стати массив объявляется как char G[12], а не как char[12] G?


R>Ну тут я затрудняюсь ответить, таков уж синтаксис. Если рассуждать в таком ключе, то можно спросить: "почему объявление функции выглядит как char


Вот сам синтаксис объявления переменной я считаю нелогичным и неудобным. Поэтому typedef, который его копирует, язык не поворачивается назвать логичным и удобным
Re[8]: А это чего у нас такое будет?
От: rg45 СССР  
Дата: 18.05.06 08:17
Оценка:
" Кодёнок " <16798@users.rsdn.ru> wrote in message news:1903294@news.rsdn.ru...
> Здравствуйте, rg45, Вы писали:
>
>>> А с какой стати массив объявляется как char G[12], а не как char[12] G?
>
> R>Ну тут я затрудняюсь ответить, таков уж синтаксис. Если рассуждать в таком ключе, то можно спросить: "почему объявление функции выглядит как char
>
> Вот сам синтаксис объявления переменной я считаю нелогичным и неудобным. Поэтому typedef, который его копирует, язык не поворачивается назвать логичным и удобным

Наверное, рациональное зерно в этом есть. Правила разбора выражений могли бы здорово упроститься, если бы, например, ссылка на массив объявлялась не так: char (&ref)[12], а так: char[12]& ref. А при разборе таких выражений как функция, возвращающая указатель на функцию вообще окосеть можно:
//foo - функция, принимающая агрумент типа const char* 
//и возвращающая указатель на функцию с сигнатурой void f(int)
void (*foo(const char*) ) (int);


Конечно, при помощи промежуточных typedef можно сделать это выражение гораздо более читабельным, но не всегда это возможно, например при специализации шаблонов, промежуточные typedef сделать не получается.
Posted via RSDN NNTP Server 2.0
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[6]: А это чего у нас такое будет?
От: gear nuke  
Дата: 18.05.06 10:33
Оценка: 4 (2) +1
Здравствуйте, Кодёнок, Вы писали:

Кё>А с какой стати массив объявляется как char G[12], а не как char[12] G?


Наследие B and BCPL. И массивы тесно связаны с поинтерами, в раннем С и поинтеры объявлялись не так, как сейчас:

Embryonic C

NB existed so briefly that no full description of it was written. It supplied the types int and char, arrays of them, and pointers to them, declared in a style typified by

int i, j;
char c, d;
int iarray[10];
int ipointer[];
char carray[10];
char cpointer[];

The semantics of arrays remained exactly as in B and BCPL: the declarations of iarray and carray create cells dynamically initialized with a value pointing to the first of a sequence of 10 integers and characters respectively. The declarations for ipointer and cpointer omit the size, to assert that no storage should be allocated automatically.


Dennis M. Ritchie "The Development of the C Language"

Хотя потом для поинтеров "спецсимвол" перенесли до имени. А для массивов — нет, видимо следуя принципу — синтаксис объявления напоминает использование.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[7]: А это чего у нас такое будет?
От: Константин Л. Франция  
Дата: 18.05.06 11:22
Оценка:
Здравствуйте, gear nuke, Вы писали:

И зря, c#'ный type[] var мне больше нравится.
Re[8]: А это чего у нас такое будет?
От: gear nuke  
Дата: 18.05.06 12:45
Оценка:
Здравствуйте, Константин Л., Вы писали:

КЛ>И зря, c#'ный type[] var мне больше нравится.


Да пожалуй все проблемы С и С++ — следствия обратной совместимости. А когда их предки развивались, были совсем другие проблемы.

и так:
char i,*p,a[5];
писали не от хорошей жизни, а т.к памяти было мало. Это сейчас сорец в 20Кб смешным выглядит, а когда-то такой гигантский размер для ядра ОС был роскошью.

Это сейчас сидят толпы академиков пишут научные труды и сочиняет самые правильные языки. А тогда несколько хакеров-самоучек накатали на коленке ОС да и компилятор заодно. И как люди этим пользуются, когда есть Оберон
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[2]: Массив в динамической памяти
От: Кодт Россия  
Дата: 18.05.06 14:45
Оценка: 1 (1)
Здравствуйте, Draqon, Вы писали:

D>Советую глянуть в сторону std::vector<TStruct>.


Или boost::array<TStruct,N>.
Кстати, boost::array<T,N> это STL-совместимая обёртка над T data[N]. То, что ты хотел написать, но обломался об синтаксис С++.

А зачем тебе динамически размещаемый массив фиксированного размера?
Перекуём баги на фичи!
Re[3]: Массив в динамической памяти
От: small_cat Россия  
Дата: 19.05.06 02:40
Оценка:
Здравствуйте, Кодт, Вы писали:

К>А зачем тебе динамически размещаемый массив фиксированного размера?


Массив большой, не хочу на стеке размещать. Опять же, хотелось единообразия для последующей упаковки его в структуру.
- Простите, профессор, не пса, а когда он уже был человеком.
— То-есть он говорил? Это еще не значит быть человеком. (с) Булгаков
Re[4]: Массив в динамической памяти
От: Кодт Россия  
Дата: 19.05.06 12:02
Оценка:
Здравствуйте, small_cat, Вы писали:

К>>А зачем тебе динамически размещаемый массив фиксированного размера?


_>Массив большой, не хочу на стеке размещать. Опять же, хотелось единообразия для последующей упаковки его в структуру.


Если не заморачиваться с чистотой типов, то достаточно T* arr = new T[N]; (здесь теряется compile-time информация о размере массива).
Опять же, vector<T> arr(N); (информация о размере доступна в run-time, через arr.size()).

А если хочется compile-time, то boost::array<T,N> или его аналоги. Но там будет некрасивый доступ к элементам:
typedef boost::array<T,N> my_array;
my_array *parr = new my_array;
std::vector<T> vec(N);
T* arr = new T[N];

(*parr)[k] = T(123);
vec[k] = T(123);
arr[k] = T(123);
Перекуём баги на фичи!
Re[2]: Массив в динамической памяти
От: MuTPu4  
Дата: 19.05.06 22:35
Оценка: 12 (1)
Здравствуйте, rg45, Вы писали:

R>Выражение new TStructArray эквивалентно выражению new TStruct[N]. Т.е. вданном случе вместо operator newвызывается operator new[].

Очень инетересно, всегда был уверен, что вызываемый operator new зависит от синтаксиса выражения new, а не от типа. Если кому интересно, вот подтверждение из стандарта:

(5.3.4/5):

When the allocated object is an array (that is, the direct-new-declarator syntax is used or the new-type-id or type-id denotes an array type)
...


(5.3.4/8):

...
If the allocated type is a non-array type, the allocation function’s name is operator new and the deallocation function’s name is operator delete. If the allocated type is an array type, the allocation function’s name is operator new[] and the deallocation function’s name is operator delete[].

 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.