Domanda

I am doing this in Visual Studio 2010.

I call function that returns vector of structures. Then I store first vector element (a struct) into local struct and then access string member of that structure, I get correct value.

But if I access the same string value by applying square brackets, straight to the function call itself, I get garbage result.

struct stNameAge
{
    char Name[64];
    int Age;
};

typedef std::vector<stNameAge> NamesAndAges;

NamesAndAges GetNamesAndAges()
{
    stNameAge nameage;
    strcpy_s (nameage.Name, 64, "My name goes here"); 
    nameage.Age = 23; 

    NamesAndAges nameandages;
    nameandages.push_back(nameage);

    return nameandages;
}

int _tmain(int argc, _TCHAR* argv[])
{
    stNameAge nameage = GetNamesAndAges()[0];

    char* MyName1 = nameage.Name ; // I get correct value of name here
    int MyAge1 = nameage.Age ;    // I get correct value here

    char* MyName2 = GetNamesAndAges()[0].Name ; // *** I get garbage value here ***
    int MyAge2 = GetNamesAndAges()[0].Age ; // I get correct value here

    return 0;
}

I am really clueless here. Can someone please explain why is it happening?

EDITED: (Added the new code below)

If I keep vector global, still its the same case. I believe returning copy of vector itself is not good idea.

struct stNameAge
{
    char Name[256];
    int Age;
};

typedef std::vector<stNameAge> NamesAndAges;

NamesAndAges nameandages;

NamesAndAges GetNamesAndAges()
{
    stNameAge nameage;
    strcpy_s (nameage.Name, 64, "My name goes here"); 
    nameage.Age = 23; 

    nameandages.push_back(nameage);

    return nameandages;
}

int _tmain(int argc, _TCHAR* argv[])
{
    // Function returning vector of structs 
    stNameAge nameage = GetNamesAndAges()[0];

    char* MyName2 = GetNamesAndAges()[0].Name ; // *** I get garbage value here ***

    char* MyName1 = nameage.Name ; // I get correct value of name here

    return 0;
}
È stato utile?

Soluzione

There's a subtle difference between the two where in the first case you're copying valid values to another valid variable while in the second there's no way to save the "result".

In the first occurrence you're using a temporary value on the stack to create your vector but then you're returning it and copy-assigning a value to another variable that you can safely use

stNameAge nameage = GetNamesAndAges()[0];

In the second you're creating a temporary vector, requesting an element but asking for a pointer to that element. When the vector gets destroyed, the pointer is no longer valid

char* MyName2 = GetNamesAndAges()[0].Name ;

Can you see the difference between the two cases?

In pseudo-code we might summarize with the following

int nameage;
int *pointer;
{
  int value = 44; // The value you're interested in

  nameage = value; // You can safely use nameage from this point forward
  pointer = &value; // When the scope ends, there's no guarantee you'll be pointing to valid data
}

// nameage is valid here, pointer is likely not and even if it is it's undefined behavior

Altri suggerimenti

When you write this:

stNameAge nameage = GetNamesAndAges()[0];

The returned object (since it is local to the function) is destroyed, but before the destruction takes place, the first object (from the vector) is copied to nameage variable. That is why it works.

However, when you write:

char* MyName2 = GetNamesAndAges()[0].Name;

Here, since Name is a pointer, it still points to the same address which doesn't belong to the program anymore (because the returned object is destroyed). So MyName2 points to the destroyed object.

int MyAge2 = GetNamesAndAges()[0].Age ;

Same as first. The object is copied.

In all cases, copy occurs. So why the second doesn't work, but first and third work? Well, because when a pointer is copied, it still points to the same object — the object being pointed to by the pointer is NOT copied, so in the second case, the object (pointed to by the pointer) is destroyed but the copied pointer stills points to it.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top