c++ классы с полями-указателями

Evgeny_T


class One
{
char *str
public:
One(int count) {str = new char[count];}
};

class Two
{
One *one;
public:
Two{ one = new One(5)} //при отладке говорит, что здесь происходит ошибка.
};


int main
{
Two *two;
two = new Two; //segmenation fault
}

Пожалуйста, помогите разобраться.

Evgeny_T

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

okis

Пересобери всё целиком. Тут всё правильно (в смысле должно работать только не хватает пары точек с запятой.
Напиши лучше компилятор и какой командой собираешь.

Oper

в этом коде все корректно, за исключением того, что две точки с запятой пропущены :)

Evgeny_T

Спасибо, компиллятор g++ (mingw) под dev-cpp. Буду думать дальше.

Evgeny_T

Когда в конструктор Two создается объект one, то вылазит ошибка:
http://pic.ipicture.ru/uploads/091208/Qrr5QsUWuh.jpg

Evgeny_T

А потом еще dev-cpp говорит, что произошла ошибка сегментации.

asvsergey

Может у тебя ошибка на выходе из main ничего не удаляется, и умная вижуал студия подсказывает?

okis

> dev-cpp

asvsergey

> dev-cpp

На скриншоте написанно Visual c++, это меня смутило.

okis

Значит компилятор у него не mingw, а оттуда проблемы с линковкой. Это тоже предположение.

Werdna

Аффтар, ты пишешь плохо, очень плохо.
Давай по порядку. Если размер не будет меняться во время исполнения, то лучше так:

template <unsigned _SZ>
class Huyas
{
char buf[_SZ];
public:
Huyas { memset(buf, 0, _SZ); }
};

Или вообще используй std::tr1::array, я вот последний люблю.
Если же надо динамически, то по идее надо писать аллокатор, но можно и так:

template <unsigned _SZ>
class Huyas
{
char *buf;
public:
Huyas(unsigned _SZ) { buf = new char[_SZ]; memset(buf, 0, _SZ); }
[b] Huyas(const Huyas &h);[/b]
~Huyas { delete[] buf; }
[b] Huyas& operator=(const Huyas &h);[/b]
};

И использовать так:
 Huyas a(666); 

Или так:
 Huyas *a = Huyas(666); ... delete a; 

Dasar

Huyas(unsigned _SZ) { buf = new char[_SZ]; memset(buf, 0, _SZ); }
memset зачем?
new по стандарту гарантирует, что выделенная память и так уже обнулена

tonchik

Попробуй так:
Two:one(new One(5{}

Evgeny_T

Всем спасибо за ответы, тут выяснилось, что если в two делать даже
char *str;
А в конструкторе:
str = new char [n];
То вылетает та самая ошибка. Может, нужен конструктор копирования?

okis

Ошибка у тебя в твоей стандартной библиотеке или ещё где-то. Можешь ассемблерный листинг показать?
Это можно сделать добавив в вызов gcc ключ -S.

kokoc88

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

okis

Да у него там вполне полный листинг. И компилируется и работает (если, конечно, не считать пары отсутствующих точек с запятой, о которых  и я указали выше).

kokoc88

Да у него там вполне полный листинг.
У него там не полный листинг, а какой-то некомпилирующийся пример. В полном листинге может оказаться что угодно кроме кода, который он написал.

ppplva

memset зачем?
new по стандарту гарантирует, что выделенная память и так уже обнулена
Не гарантирует. Кажется, именно для POD.

okis

> Кажется, именно для POD.
Да, именно так.

pitrik2

new по стандарту гарантирует, что выделенная память и так уже обнулена
ты с++ с сишарпом путаешь?

doublemother

Это логичная в общем-то мысль - раз для объектов вызывается конструктор по умолчанию, то можно предположить, что POD-типы инициализируются "стандартными" нулями.

pitrik2

то можно предположить, что POD-типы инициализируются "стандартными" нулями.
эээ
у тебя динамический массив - POD-тип?
ты тоже с++ с сишарпом путаешь?

margadon

да, вот читаю такое и всё больше убеждаюсь, что плюсы - просто какой-то набор исключений и нелогичностей по сравнению с другими языками :)

doublemother

Виноват, был дурак, путаю.

Dasar

ты с++ с сишарпом путаешь?
не путаю.
как одно из отличий new от malloc - проговаривалось обнуление памяти (в том числе и у страуструппа).
а вот то, что для массива pod-ов, выделенного динамически, в C++ нет даже синтаксиса для его штатного обнуления - вот это я уже подзабыл.
ps
для выделения pod-структуры такой синтаксис, например, есть

Andbar

#include <stdio.h>
#include <string>

class A
{
public:
int val;
};

int main
{
A *a = new A[5];
for(int i=0; i<5; i++) printf("%d,", a[i].val);
printf("\n");
delete [] a;
return 0;
}
cl выдаёт нули только если в класс добавить виртуальный метод, gcc выдаёт нули в любом случае (даже если заменить класс на простой int.
Кроме того, не редко видел реализацию operator new именно через malloc, а не через calloc.

okis

cl выдаёт нули только если в класс добавить виртуальный метод
а если конструктор ?
operator new именно через malloc, а не через calloc
operator new[] ?

ppplva

Omg, прочитай уже стандарт вместо того что бы проверять undefined behavior на частных случаях!
gcc выдаёт нули в любом случае (даже если заменить класс на простой int.

Добавь цикл вокруг main.

Dasar

Это логичная в общем-то мысль - раз для объектов вызывается конструктор по умолчанию, то можно предположить, что POD-типы инициализируются "стандартными" нулями.
с одной стороны - оно так и есть.
выделенный вот так int - обязан быть нулевым
[c]
int * p = new int;
[/c]
но вот выделение массива является исключением - только его не зануляют

yroslavasako

Аффтар, ты пишешь плохо, очень плохо.
темплаты - не всегда выход. У них есть и преимущества, и недостатки. В некоторых компаниях темплаты вообще политикой запрещены

ppplva

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

margadon

омг, мне жалко их
должно быть, их софт писался на старых версиях явы, а потом переписывался на плюсы чтобы быть хоть чуток побыстрее?

yolki

кстати, тут уже намекали.
компилятор один, а рантайм от другого. может, в этом ошибка?

pav7

Йо, Пеонизд, запости какой-нибудь свой код? А то я все анекдоты уже прочитал.
Оставить комментарий
Имя или ник:
Комментарий: