K
K
kakker2016-07-16 01:16:01
C++ / C#
kakker, 2016-07-16 01:16:01

How to keep a stack variable alive?

There is this terrible function:

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: ;
    }
}

And such a modest structure for transferring values:
struct Value {
    QString typeName; // строка
    void *ptr;
}

The point is that where I call the someFunction() function , I do not need to know the types of the values ​​being passed (they are not known to me at all), but the value itself needs to be passed to another similar function that will know what to do with void *ptr. How can I copy
this value (variable t ) into Value ? does not live long, and it is not a fact that it will survive at all. only works if *ptr was previously allocated memory for SomeTypeOne , but I can't do that because SomeTypeOne is not known in my scope. How to be?
value.ptr = reinterpret_cast<void*>(&t);
*reinterpret_cast<SomeTypeOne*>(value.ptr) = t;

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
AtomKrieg, 2016-07-16
@AtomKrieg

Only further calls can extend the life of the variable on the stack. This is the essence of the stack. As soon as you exit the function, the memory is freed for the variables of other functions and all pointers to variables inside become invalid.

template<typename T>
callbackFunction(T &t) {...}

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

In general, you have here a design pattern called a factory method. No need to invent a bicycle, but you need to look at books.

A
abcd0x00, 2016-07-16
@abcd0x00

First, don't put curly braces in cases, learn the basics of C++ first.
Second, what you're asking is done using new. You get the data, make new for it, then save the data there and attach this memory to the structure.

K
Konstantin Stepanov, 2016-07-21
@koronabora

Some terrible memory operations.
The very essence of the stack is the storage of temporary values ​​that will be automatically removed from memory when the subroutine (procedure or function) exits.
There are two solutions:
1) Use recursion, thus filling the stack and not allowing to remove what is required. But, this is a rather illiterate approach. Recursion has its own range of tasks and is a bit not for such things.
2) Do the right thing - allocate memory on the heap (heap) using the new operator, and pass the pointer to the memory area on the heap inside the function.

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;
    }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question