Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does my result data returned as void* gets broken?

Tags:

c++

I am working in a project with a huge legacy code base and have been trying to re-design parts of it to get away from old c-style code.

I've run into a problem and have prepared a short program to explain.

The legacy interface I am using needs me to pass a pointer to the result data as void* and I would like to avoid having to change this.

The unique_ptr in the example just goes to demonstrate, that in my real code base everything working on the data is using smart pointers to manage memory.

My problem is, that the result data gets broken (see last output line / last call to printPayload); everything is 0 at the end, but it doesn't seem to be a problem with converting to the void* and back as shown by the 2nd and 3rd output line.

Is this a problem related to temporaries? I don't get it...

I hope this kind of problem has relevance for some of you.

#include <iostream>
#include <memory>

struct Payload
{
    long a;
    int b;
    int c;

    Payload() : a(), b(), c() {}
    Payload(long setA, int setB, int setC) : a(setA), b(setB), c(setC) {}
};

void printPayload(const Payload& printThis)
{
    std::cout << "payload -- a: " << printThis.a << " b: " << printThis.b << " c: " << printThis.c << std::endl;
}

void doSomething(Payload* sourceData, void* targetData)
{
    if (!sourceData) return;

    std::unique_ptr<Payload> sourceDataUnique(sourceData);

    sourceDataUnique->a = 222;
    sourceDataUnique->b = 333;
    sourceDataUnique->c = 444;

    printPayload(*sourceDataUnique);

    targetData = reinterpret_cast<void*>(sourceDataUnique.release());

    printPayload(*(reinterpret_cast<Payload*>(targetData)));
}

int main(void)
{
    Payload* myPayload = new Payload(14, 8, 1982);
    Payload myResult;

    printPayload(*myPayload);

    doSomething(myPayload, &myResult);

    printPayload(myResult);
}

Output:

payload -- a: 14 b: 8 c: 1982
payload -- a: 222 b: 333 c: 444
payload -- a: 222 b: 333 c: 444
payload -- a: 0 b: 0 c: 0
like image 575
Mr.Infredible Avatar asked Oct 19 '16 07:10

Mr.Infredible


People also ask

What should void * return?

A void function can returnA void function cannot return any values. But we can use the return statement. It indicates that the function is terminated.

Does void mean no return?

In computer programming, when void is used as a function return type, it indicates that the function does not return a value.

What happens if you return in a void method?

It exits the function and returns nothing.

What does return value void mean?

Void functions are created and used just like value-returning functions except they do not return a value after the function executes. In lieu of a data type, void functions use the keyword "void." A void function performs a task, and then control returns back to the caller--but, it does not return a value.


2 Answers

targetData is a local variable to doSomething. After you assign an address to it, it goes out of scope.

You never actually assign to myResult.

like image 81
StoryTeller - Unslander Monica Avatar answered Oct 19 '22 23:10

StoryTeller - Unslander Monica


In your code, the parameter targetData is local to doSomething function (i.e., any change is lost after you exit the scope of the function). However, *targetData refers to the variable myResult declared in main function.

So, the following code should work:

void doSomething(Payload* sourceData, void* targetData)
{
    if (!sourceData) return;

    sourceData->a = 222;
    sourceData->b = 333;
    sourceData->c = 444;

    printPayload(*sourceData);

    Payload* td = static_cast<Payload*>(targetData);
    *td = *sourceData;
    printPayload(*td);
}
like image 31
Daniele Pallastrelli Avatar answered Oct 19 '22 23:10

Daniele Pallastrelli