LINUX.ORG.RU

new в конструкторе

 ,


0

1

Подскажите, пожалуйста, почему такой код вызывает сегфолт:

class A
{
    public:
        A()
        {
            a = new A;
        }
    private:
        A* a;
};

int main()
{
    A a;
}
Интуитивно не понятно. Перерыл кучу форумов, открывал Страуструпа - нигде не могу найти объяснения.


Не спец по крестам, но по-моему создавать надо так:

a = new A();

А если ты в конструкторе вызываешь новый конструктор, то у тебя должен быть стек оверфлоу по идее.

vurdalak ★★★★★ ()

«конструкция new A вызывает конструктор класса A, в котором есть конструкция new A которая...„нутыпонел

//фуцк! где этот автор по кавычкам?!

aol ★★★★★ ()
Последнее исправление: aol (всего исправлений: 1)

Бесконечная рекурсия. В конструкторе A() создается объект класса A, и у него вызывается тот же самый конструктор A(). Ну и так далее.

anonymous ()
Ответ на: комментарий от vurdalak

a = new A();

Если не ошибаюсь, они эквивалентны. В обоих случаях вызывается конструктор по-умолчанию.

А если ты в конструкторе вызываешь новый конструктор, то у тебя должен быть стек оверфлоу по идее.

Мне тоже так кажется, но кидает именно сегфолт.

devpony ()

бесконечная рекурсия - итог переполнение

зы: куда уж интуитивнее

fornlr ★★★★★ ()
Последнее исправление: fornlr (всего исправлений: 1)
Ответ на: комментарий от nanoolinux

Это тестовое задание, а не практическая задача.

devpony ()
Ответ на: комментарий от devpony

А ты чего ждешь? Указатель стека вышел за пределы выделенного программе пространства и пытается туда писать => SIGSEGV

ddos3 ()
Ответ на: комментарий от devpony

Нет, это именно стек кончается. Просто стек тоже в памяти, и операционке пофиг, что там кончилось: пишешь, куда нельзя, - лови SIGSEGV. Прогони программу под walgrindом, как аноним, он тебе тоже про стек напишет.

ddos3 ()
Ответ на: комментарий от devpony

Что бы твоя программа работала тебе нужен стек бесконечно большого размера. Да, именно - бесконечного. Подумай над этим.

nanoolinux ★★★★ ()
Ответ на: комментарий от devpony

Если не ошибаюсь, они эквивалентны. В обоих случаях вызывается конструктор по-умолчанию.

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

DELIRIUM ☆☆☆☆☆ ()

Надо не форумы рыть, и не трупа читать, а сделать отладочный вывод.

Miguel ★★★★★ ()
Ответ на: комментарий от DELIRIUM

в одном случае будут проинициализированы все члены класса, а в другом только те, которые POD

Эм, а где такое написано? Глянул стандарт, там по этому поводу указано, что инициализатор не является обязательным и в случае его отсутствия вызывается конструктор по умолчанию.

Может путаница вышла из-за такого синтаксиса?

int *uninitializedIntArray = new int[10];
int *zeroInitializedIntArray = new int[10]();

xaizek ★★★★★ ()
Ответ на: комментарий от xaizek

был немного неправ:

#include <iostream>
#include <cstring>

using namespace std;

class ST {
     public:
          ST() {
               cout << "ST constructor executed" << endl;
          }
};

class T {
     public:
          int i;
          ST st;
};

int main() {
     char mem[1000];
     T *t_ptr;

     memset(mem, 0x0F, sizeof(mem));
     t_ptr = new(mem) T;
     cout << "new T: " << int(t_ptr->i) << endl;

     memset(mem, 0x0F, sizeof(mem));
     t_ptr = new(mem) T();
     cout << "new T(): " << int(t_ptr->i) << endl;

     T t;
     cout << "T t: " << int(t.i) << endl;

     t = T();
     cout << "t = T(): " << int(t.i) << endl;

     return 0;
}
DELIRIUM ☆☆☆☆☆ ()

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

vzzo ★★★ ()
Ответ на: комментарий от DELIRIUM

Спасибо за пример, понял. Изначально не было ясно, что речь идёт о классах являющихся POD-типами.

xaizek ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.