Задать вопрос

Как сохранить жизнь переменной стека?

Имеется такая ужасная функция:

void someFunction(int index, Value &value) {
    switch(index) {
    case 0: {
        SomeTypeOne t = someObject->someMethodOne(); // возвращает SomeTypeOne
        value.type = "SomeTypeOne";
        // value.ptr = ???
    } break;

    case 1: {
        SomeTypeTwo t = someObject->someMethodTwo(); // возвращает SomeTypeTwo
        value.type = "SomeTypeTwo";
        // value.ptr = ???
    } break;
    
    default: ;
    }
}


И такая скромная структура для перноса значений:

struct Value {
    QString typeName; // строка
    void *ptr;
}


Смысл в том, что там где я вызываю функцию someFunction(), мне не нужно знать типы передаваемых значений (они мне вообще неизвестны), но само значение нужно передать в другую похожую функцию, которая будет знать что делать с void *ptr.
Как мне это значение (переменная t) скопировать в Value?
value.ptr = reinterpret_cast<void*>(&t); живёт не долго, да и не факт что выживет вообще.
*reinterpret_cast<SomeTypeOne*>(value.ptr) = t; работает только если в *ptr была заранее выделена память под SomeTypeOne, но этого я делать не могу, так как тип SomeTypeOne не известен в моей области видимости. Как быть?
  • Вопрос задан
  • 544 просмотра
Подписаться 3 Оценить 2 комментария
Пригласить эксперта
Ответы на вопрос 3
AtomKrieg
@AtomKrieg
Давай я поищу в Google за тебя
Только дальнейшими вызовами можно продлить жизнь переменной на стэке. Это суть стэка. Как только вы выходите из функции, память освобождается под переменные других функции и все указатели на переменные внутри становятся невалидными.
template<typename T>
callbackFunction(T &t) {...}

void someFunction(int index) 
{
    switch(index) 
    {
        case 0: callbackFunction ( someObject->someMethodOne() );
            break;
   ...


Вообще у вас тут паттерн проектирования под названием фабричный метод. Не надо придумывать велосипед, а надо смотреть в книжки.
Ответ написан
@abcd0x00
Во-первых, не надо ставить фигурные скобки в case'ах, выучи основы C++ для начала.
Во-вторых, то, что ты спрашиваешь, делается с использованием new. Получаешь данные, делаешь под них new, потом сохраняешь данные туда и прицепляешь эту память к структуре.
Ответ написан
@koronabora
Человек
Какие-то страшные операции с памятью.

Сама суть стэка - это хранение временных значений, которые автоматически будут удалены из памяти при выходе из подпрограммы (процедуры или функции).

Решения два:
1) Использовать рекурсию, тем самым забивая стек и не давая удалить то, что требуется. Но, это достаточно безграмотный подход. У рекурсии свой круг задач и она немного не для таких вещей.
2) Действовать как правильно - выделять память в куче (heap), используя оператор new, а внутрь функции передавать указатель на область памяти в кучу.

void someFunction(int index, Value *value) {
	if (value!=NULL)
		switch(index) {
		case 0: 
			SomeTypeOne t = someObject->someMethodOne(); // возвращает SomeTypeOne
			value->type = "SomeTypeOne";
			break;
		case 1: 
			SomeTypeTwo t = someObject->someMethodTwo(); // возвращает SomeTypeTwo
			value->type = "SomeTypeTwo";
			break;
		}
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы