[Вопрос] Массивы в C++

pogreb38

Плиз, расскажите, туплю.
Есть класс CLASS, мне нужен массив array из элементов этого класса.
Как его объявить? и есть ли такая конструкция в С++ вообще?
На конструкции CLASS array[10] вылетает с ошибкой памяти (Stack overflow) еще даже вроде до запуска программы, на этапе сборки, после третьей попытки я поняла, что видимо так делать неправильно
:grin:
Вектор создается без проблем vector <CLASS> array, но нужен именно массив....

mkrec

а что у тебя за CLASS?

Andbar

На конструкции CLASS array[10] вылетает с ошибкой памяти (Stack overflow) еще даже вроде до запуска программы
1. не следует выделять слишком много памяти на стеке, это может ухудшить производительность в силу особенностей реализации стека (кстати, code analyzer из вижуалстудии ругается на подобные вещи вместо этого выделяй память в куче;
2. имхо, плохая идея так класс называть
(а ещё можно умудриться бесконечную рекурсивную функцию вызвать из конструктора, но ты пишешь, что прога даже не запускается...)

okunek

Только потом не рассказывай топикастеру про перегрузку операторов new и delete, если она воспользуется твоим кодом

Andbar

код был неправильный :grin:
Отсутствие в STL аналога std::auto_ptr, который удаляет через delete[], всегда мне не нравилось (приходилось писать свой враппер для этого дела)

pogreb38

Ну, CLASS и array - это я тут написала, для простоты.
У меня большая программа, много где надо такую конструкцию использовать...
Строчка std::auto_ptr<CLASS> array(new CLASS[10]); не компилится, ругается error C2059: syntax error : 'new'
А что она значит-то? моих знаний С++ не хватает на то, чтобы распарсить это :crazy:
еще есть варианты сделать массив из элементов класса?... :(

Andbar

error C2059: syntax error : 'new'
гм... А можно полностью тот кусок кода?
А что она значит-то? моих знаний С++ не хватает на то, чтобы распарсить это :crazy:
std::auto_ptr - это шаблонный класс, который хранит в себе указатель и освобождает его при выходе из блока, в котором он существует. Например, если в начале некой функции объявить
std::auto_ptr<int> someintptr(new int);
то будет выделена память под один int (new int) и указатель на неё будет сохранён в объекте someintptr. При этом, перед выходом из функции эта память будет автоматически освобождена.
Проблема только в том, что память будет освобождаться оператором delete и если нам нужен delete[], то такой вариант не подходит.

okunek

Блин, вообще, не используй это!
У тебя деструкторы не будут вызваны для 9-и элементов как минимум. И вообще, это глюк.
Выделяй память с помощью CLASS* array = new CLASS[10] и удаляй её руками через delete [] array.

klyv

sizeof(CLASS) чему равно? не удивлюсь, если большоому числу.
большие массивы лучше делать в куче (т.е. CLASS* arr = new CLASS[10])

Andbar

Выделяй память с помощью CLASS* array = new CLASS[10] и удаляй её руками через delete [] array.
при таком подходе придётся следить за исключениями и всеми выходами из текущего блока. Я бы нагуглил описание шаблонного класса auto_array и воспользовался бы им (если не используется какой-нить boost)

pogreb38

Не компилится :( видимо я вам мало инфы предоставляю, вотчасть кода (ну, то, что относится к проблеме).
Идея - моделрование эволюции вируса ВИЧ в крови человека, это так, лирическое отступление.
class GENOM
{
public:
short len;
short genom[LEN];
};
class VIRAL_ENTITY
{
public:
GENOM ViralGenom[2];
};
class CELL
{
public:

VIRAL_ENTITY * ImplantedViruses = new VIRAL_ENTITY[10];
}
Ругается ошибкой и ворнингом такими:
warning C4291: 'void *operator new[](size_t) throw(...)' : no matching operator delete found; memory will not be freed if initialization throws an exception
error C2864: 'ImplantedViruses' : only const static integral data members can be initialized inside a class or struct
Вот...если в классе VIRAL_ENTITY пишу
class VIRAL_ENTITY
{
public:
// GENOM ViralGenom[2];
int a;
};
ворнинг пропадает, но ошибка остается...

okunek

omfg :cry2:

pogreb38

что такое omfg? :cool:

mkrec

> error C2864: 'ImplantedViruses' : only const static integral data members can be initialized inside a class or struct
Ну так все ведь написано.

okunek

Ну, кратко говоря, выделение/освобождение памяти тебе надо производить в какой-то функции, например в конструкторе/деструкторе.

Andbar

VIRAL_ENTITY * ImplantedViruses = new VIRAL_ENTITY[10];
Лучше почитай про конструкторы и деструкторы в классах прежде чем продолжать что-то писать.

milanadiana


#define LEN 200
class GENOM
{
public:
short len;
short genom[LEN];
};

class VIRAL_ENTITY
{
public:
GENOM ViralGenom[2];
};

class CELL
{
public:
VIRAL_ENTITY * iv;

CELL {
iv = new VIRAL_ENTITY[10];
}

~CELL {
delete []iv;
}
};

int main {
CELL cell;
return 1;
}


— код проверен GCC
Перепелка, не пользуйся ООП, пожалуйста. Ну пожалуйста! Пользуйстя структурками, процедурками, но не классами..

Andbar

А кто будет деструктор писать с очисткой выделенной памяти? Пушкин?

kokoc88

Перепелка, не пользуйся ООП, пожалуйста. Ну пожалуйста! Пользуйстя структурками, процедурками, но не классами..
Где деструктор?
Класс конструируется без скобок.

milanadiana

Простите-с, впендюрил. Можно и со скобками.

kokoc88

Можно и со скобками.
Запись вида "myclass foo;" - это прототип функции. Со скобками конструировать класс в твоём примере нельзя. Тем более у автора темы Visual C++

milanadiana

Точно, чувак, ты прав, а я мудак. И почему я так написал? Раньше ведь писал-писал, и никогда так не делал... Видимо языки в голове начали смешиваться и давать странные мжвячни результаты.

milanadiana

А вообще топикстартер, приходи к нам в лабу, мы с Raul_duke-ом тебя посадим за свободную машинку и будешь компилиццо и пускаться на 8-процессорной тачке с gentoo.

klyv

class CELL
{
public:
    
VIRAL_ENTITY * ImplantedViruses = new VIRAL_ENTITY[10];
}
class CELL
{
public:
    
VIRAL_ENTITY * ImplantedViruses;
CELL { ImplantedViruses = new VIRAL_ENTITY[10]; }
~CELL { delete[] ImplantedViruses; }

}
вот про это тут все

pogreb38

Спасибо огромное, мальчики!
последний вариант начал компилиться и по крайней мере не вылетает с переполненным стеком сходу...
На счет не использовать ООП...эх, раньше надло было думать, и даже не полгода назад, когда я начала эту прогу писать, а 7 лет назад, когда факультет выбрала...Блин, в кулинарный техникум идти надо было!....
Переписывать уже нет возможности, научнику хоть что-то рабочее надо показать...
Еще раз всем ОГРОМНОЕ СПАСИБО!
возникнут идиотские вопросы, буду писать... ;)

Sanjaz

Минимум изменений в исходном коде:

class GENOM
{
public:

short len;
short genom[LEN];
};

class VIRAL_ENTITY
{
public:
GENOM ViralGenom[2];
};

class CELL
{
public:

VIRAL_ENTITY ImplantedViruses[10];

};

Добавлен символ ; после класса CELL.
Плюс такой, что не надо заморачиваться с выделением и освобождением памяти. Все само корректно отработает.
Скомпилировано под MinGW

Andbar

Плюс такой, что не надо заморачиваться с выделением и освобождением памяти.
Ага, особенно если LEN порядка MAX_INT :LOL1:

Sanjaz

Если LEN порядка MAX_INT, то девушке понадобится порядка 16,777,216 ТЕРАБАЙТ памяти.
Я думаю, что девушка понимает что происходит в строчке
short genom[LEN];
.

Andbar

Если LEN порядка MAX_INT, то девушке понадобится порядка 16,777,216 ТЕРАБАЙТ памяти.
гм... если MAX_INT 32-битный, то гораздо меньше, если же он 64-битный, то на порядок больше для экземпляра CELL.
На счёт значения LEN я заикнулся из-за того, что девушка в начале темы жаловалась на переполнения стека и это, как бы, косвенно указывает на то, что она создаёт такие объекты на стеке и они довольно не маленькие. Значит, имеет смысл держать хотя-бы часть данных в куче. Довольно удобно в кучу помещать данные, находящиеся внутри используемого объекта, т.к. выделять каждый раз память и освобождать её неудобно.
Т.е., например, экземпляры CELL создаём в куче, а в нём массив ImplantedViruses размещаем в куче. Хотя мне кажется более логичным GENOM::genom в кучу вынести.

Missi4ka

Вот так само будет выделяться и освобождаться (ЗЫ: не компилил, могут быть опечатки)


template <int LEN>
struct ARRAY {

int *values;

ARRAY { values = new int[LEN]; }
~ARRAY { delete[] values; }
operator int* { return values; }

private:
ARRAY(const ARRAY&) {}
ARRAY & operator=(const ARRAY&) {}

};

class GENOM
{
public:

ARRAY<LEN> genom;
};

class VIRAL_ENTITY
{
public:
GENOM ViralGenom[2];
};

class CELL
{
public:

VIRAL_ENTITY ImplantedViruses[10];

};

klyv

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

Missi4ka

Ну у нее ж там остальные массивы по 2-10 элементов. Или это только usecase, а на самом деле они больше?

klyv

Ну у нее ж там остальные массивы по 2-10 элементов. Или это только usecase, а на самом деле они больше?
и эти маленькие массивы содержат эти большие, для которых ты сделал smart pointer.
всяко лучше не размазывать по куче отдельные массивчики, а выделить всё одним большим куском.

Andbar

Если объектов не очень много /*читай: они не (создаются и удаляются) в цикле*/, то потеря в производительности будет не столь заметна. С другой стороны, если нужно активно работать не только с CELL, но и с объектами, которые в ней сидят, как с независимыми сущностями, то вариант с единственным выделением внутри GENOM будет немного удобнее.
Короче, я хочу сказать, что большинство соображений на тему производительности при данных обстоятельствах сводятся к информации о нескольких ошибках, которые не следует совершать, а дальше будут пустые споры до появления конкретных данных от профилировщика.

Missi4ka

smart pointer
скорее, auto_ptr :)

klyv

ну вдруг он не знает, что это такое

yulya

если подобные вопросы отнимают существенную часть полезного времени, то имеет смысл писать на яве

okunek

О, скоро тред обещает быть очень интересным :)

kruzer25

если подобные вопросы отнимают существенную часть полезного времени, то имеет смысл писать на яве
Ну, может быть, у человека задание такое в универе - написать программу на плюсах.
В данном случае, имхо, действительно, если писать на высокоуровневом быстром языке, в итоге всё будет работать быстрее, чем если ковыряться с плюсами, совершенно не представляя себе устройства всего этого.

Papazyan

++ - это вообще мусор, забыть о нем, как о страшном сне.
Оставить комментарий
Имя или ник:
Комментарий: