string has wrong size

Started by
23 comments, last by visitor 14 years, 2 months ago
Why doesn't this work?

typedef std::string str;

const str& SectorI::GetTileData() const
{
    return
        str("XXXXXXXXXXXXXXXX  XXXXXXXn") +
        str("X      XXX    XX  XX    Xn") +
        str("X      XXX              Xn") +
        str("X      XXXXX          XXXn") +
        str("X      XXX              Xn") +
        str("X      XXX              Xn") +
        str("X      XXXXXX   XX   XXXXn") +
        str("X      XXX              Xn") +
        str("X      XXXXXXXXXXXXXXXX Xn") +
        str("X      XXXXXXXXXXXXXXXX Xn") +
        str("X                       Xn") +
        str("X                       Xn") +
        str("X                       Xn") +
        str("X                       Xn") +
        str("X                       Xn") +
        str("X                       Xn") +
        str("X                       Xn") +
        str("X                       Xn") +
        str("XXXXXXXXXXXXXXXXXXXXXXXXXn");
}



The returned string has the expected data in it, however, it's size is incorrect, leading to all sorts of problems when I try to iterate over it. Specifically, GetTileData().size() returns 46419024 for some reason. Well actually, it's a different value each time, but it's always much bigger then it should be. It looks like an uninitialized variable, but that is internal to std::string and I think it is much more likely that I have a bug somewhere rather then there being a bug in the standard library. What am I doing wrong?
I trust exceptions about as far as I can throw them.
Advertisement
You are returning a const reference!!!!!
WTF???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
Oh I guess I should be returning by value in this case.
I got confused because temporaries are const references and I was returning a temporary variable. I forgot that you can't take references of a local variable and expect them to still be there.
I trust exceptions about as far as I can throw them.
Quote:It looks like an uninitialized variable, but that is internal to std::string and I think it is much more likely that I have a bug somewhere rather then there being a bug in the standard library.

If you have a bug when you are using the standard library, then the bug most likely lies in your code, not in the std.

In this case, you are returning a reference on a local object which is allocated on the stack. So this object is destroyed after the return statement. Having the correct data in it is just pure luck.
You can only return local variables by value.

And as a hint, string literals can be concatenated:

std::string SectorI::GetTileData() const{    return std::string(        "XXXXXXXXXXXXXXXX  XXXXXXXn"        "X      XXX    XX  XX    Xn"        "X      XXX              Xn"        "X      XXXXX          XXXn"//etc.        );}
Quote:Original post by Arkhyl
Quote:It looks like an uninitialized variable, but that is internal to std::string and I think it is much more likely that I have a bug somewhere rather then there being a bug in the standard library.

If you have a bug when you are using the standard library, then the bug most likely lies in your code, not in the std.

Yeah, that's what he said.

Besides, it would be better if he were to store tile data in a variable somewhere, rather that hard-code a function to return a copy of the data every time.
The SectorI class could have a member variable called tileData. That gets initialised in the constructor by calling GetTileData() then every other time it is needed, you only have to refer to the variable by reference. It also makes it easier in the future if you want to read tile data from a file.
[Window Detective] - Windows UI spy utility for programmers
Incidentally, pretty much every compiler will issue a warning for this kind of thing. For instance, with MSVC you'd get a C4172, which is a level 1 warning. If you have warnings enabled at all, MSVC will complain that you're doing something wrong.
Quote:Original post by XTAL256
Besides, it would be better if he were to store tile data in a variable somewhere, rather that hard-code a function to return a copy of the data every time.
Incidentally this is one of those times where std::string just isn't needed, you could avoid the per-invocation construction/copying using a string literal:

const char * tile_data(){    return "XXXXXXXXXXXXXXXX  XXXXXXXn"           "X      XXX    XX  XX    Xn"           "X      XXX              Xn"           "X      XXXXX          XXXn"           "X      XXX              Xn"           "X      XXX              Xn"           "X      XXXXXX   XX   XXXXn"           "X      XXX              Xn"           "X      XXXXXXXXXXXXXXXX Xn"           "X      XXXXXXXXXXXXXXXX Xn"           "X                       Xn"           "X                       Xn"           "X                       Xn"           "X                       Xn"           "X                       Xn"           "X                       Xn"           "X                       Xn"           "X                       Xn"           "XXXXXXXXXXXXXXXXXXXXXXXXXn";}
Quote:Original post by dmatter
Quote:Original post by XTAL256
Besides, it would be better if he were to store tile data in a variable somewhere, rather that hard-code a function to return a copy of the data every time.
Incidentally this is one of those times where std::string just isn't needed, you could avoid the per-invocation construction/copying using a string literal:

Depends on what you're going to do with that level data, but yeah. Then again, you'd store this sort of data in an external file. Data-driven development, no need to recompile if you just want to change some level-data.
Create-ivity - a game development blog Mouseover for more information.
I don't remember seeing any compiler warning, although it may have been lost among the hundreds of spurious warnings that Box2d always generates.

I have thought about external storage for some of the level data but I have no idea how to do it. It doesn't help that there is a ton of level specific behavior.
I trust exceptions about as far as I can throw them.

This topic is closed to new replies.

Advertisement