Thread: Problem with custom structure

  1. #1
    Registered User
    Join Date
    Aug 2004
    Posts
    193

    Problem with custom structure

    I have this structure:

    Code:
    struct MYSTRUCT {
         const char* var1;
         const char* var2;
         const char* var3;
    };
    And then I create a MYSTRUCT variable and send it like so:

    Code:
    MYSTRUCT mystruct = (MYSTRUCT){"text","test","more text"};
    SendMessage(hListBox, LB_SETITEMDATA, x, (LPARAM)&mystruct);
    And then I recieve my structure variable like so:

    Code:
    MYSTRUCT* mystructure = (MYSTRUCT*)SendMessage(hListBox, LB_GETITEMDATA, x, 0);
    Now, my problem is, I want to modify the values of the three varX variables in the structure. I've tried this:

    Code:
    GetDlgItemText(hVar1, temp_var, 255);
    mystructure->var1 = temp_var;
    GetDlgItemText(hVar2, temp_var, 255);
    mystructure->var2 = temp_var;
    GetDlgItemText(hVar3, temp_var, 255);
    mystructure->var3 = temp_var;
    SendMessage(hListBox, LB_SETITEMDATA, x, (LPARAM)mystructure);
    The problem with that is that all the values of the varX variables are equivalent to the value of the var3 variable. I'm pretty sure I'm doing something wrong, but I'm not sure how to fix it. I'm sorry if this is in the wrong section because I know I have some win32 code, but I think my problem is with the memory and actual values conflicting which is c++.

  2. #2
    Registered User
    Join Date
    Aug 2004
    Posts
    193
    I solved my own problem once again. I prefer string variables to const char* variables, so I just tried making all the const char* variables string variables and it worked. So this thread is solved.

  3. #3
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    Actually the problem is NOT solved.

    Code:
    MYSTRUCT mystruct = (MYSTRUCT){"text","test","more text"};
    SendMessage(hListBox, LB_SETITEMDATA, x, (LPARAM)&mystruct);
    As soon as that function ends, mystruct is gone; the variable is out of scope and the memory on the stack where it existed is no longer used by the struct.

    So then, when this happens:

    Code:
    MYSTRUCT* mystructure = (MYSTRUCT*)SendMessage(hListBox, LB_GETITEMDATA, x, 0);
    It's reading from the location of where mystruct USED to be.

    You'd need to do something like this:

    Code:
    MYSTRUCT * pmystruct = new MYSTRUCT("text","test","more text"); // Just create the constructor, it's not hard.
    SendMessage(hListBox, LB_SETITEMDATA, x, (LPARAM)pmystruct);
    And somewhere, when the program is exiting but the window hasn't undergone its final destruction (for example, you can do this in the handler for WM_CLOSE before it calls DestroyWindow):

    Code:
    MYSTRUCT* mystructure = (MYSTRUCT*)SendMessage(hListBox, LB_GETITEMDATA, x, 0);
    delete mystructure;
    Last edited by Cat; 10-14-2006 at 03:34 AM.
    You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    One of the disadvantages of C style strings versus the C++ string class is that operations like assignment and equality testing don't work as you'd expect. This is because you are dealing with a pointer instead of an actual object. In your case, what happened was that you were assigning the temp pointer to the pointers in your structure. Each time the string at the location pointed to by temp changed, the varX variables pointed at that new string.

    Using std::string is the right solution. If you had to use C style strings, you would want to have a non-const char* (since you are changing the value of the string after it is initialized), and you would need to allocate memory for that string. Then you would use strcpy or something similar to copy the strings. This is all more dangerous and a bigger hassle than it is worth if you can use std::strings instead.

    >> Actually the problem is NOT solved.
    I believe that with the way SendMessage works it should be ok. The function that receives the message finishes before the calling function ends. If it was PostMessage you would have that problem.
    Last edited by Daved; 10-13-2006 at 10:44 PM.

  5. #5
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    Quote Originally Posted by Daved
    I believe that with the way SendMessage works it should be ok. The function that receives the message finishes before the calling function ends. If it was PostMessage you would have that problem.
    It's not a problem with the LB_SETITEMDATA message -- as you say, the pointer is valid at that time.

    Where the problem comes in is when the pointer is retrieved with the LB_GETITEMDATA message. The struct still needs to exist at that point in time, and as it seems to be a variable local to the function doing the setting, as soon as that function ends, the pointer no longer is valid.

    It can be deceptive because the first thing one might do to test would probably be something like this:

    Code:
    void test() {
         MYSTRUCT mystruct = (MYSTRUCT){"text","test","more text"};
         SendMessage(hListBox, LB_SETITEMDATA, x, (LPARAM)&mystruct);
         MYSTRUCT* mystructure = (MYSTRUCT*)SendMessage(hListBox, LB_GETITEMDATA, x, 0);
    
         // Here you can verify the contents of mystructure and you'd find nothing wrong.
    }
    However, it ONLY works because mystruct is still in scope when the GETITEMDATA is called, because the function which created the struct hasn't returned. In general, that won't be the case. In most realistic scenarios, mystruct goes out of scope before GETITEMDATA is called, and by then the pointer is garbage.
    You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.

  6. #6
    Registered User
    Join Date
    Aug 2004
    Posts
    193
    The replies are greatly appreciated. I think the reason why it was working for was because the MYSTRUCT variable I was using was a global variable and not just a local variable, but that is good to know. I probably have a lot of memory leaks like the one you described in my code because I'm not very experienced with all the pointers and actual values and all the different variable types.

    EDIT:

    I tried this code:

    Code:
    MYSTRUCT * pmystruct = new MYSTRUCT("text","test","more text");
    And I get these errors:

    Code:
    1459 no matching function for call to `MYSTRUCT::MYSTRUCT(char*&, char*&, char*&)' 
    27 candidates are:  MYSTRUCT::MYSTRUCT() 
    27                 MYSTRUCT::MYSTRUCT(const MYSTRUCT&)
    Last edited by stickman; 10-14-2006 at 02:30 PM.

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Check out the comment made by Cat on that line of code and follow those instructions:

    // Just create the constructor, it's not hard.

  8. #8
    Registered User
    Join Date
    Aug 2004
    Posts
    193
    I thought the

    Code:
    struct MYSTRUCT {
    ...
    };
    was the constructor. Do you mind telling me what this would be? Thanks.

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    The constructor is a function with no return type that constructs the object by initializing its member variables and doing whatever other work you want it to do.

    If you don't know constructors yet, you don't need to use one here, just use MYSTRUCT * pmystruct = new MYSTRUCT, then set each member one at a time.

    >> Where the problem comes in is when the pointer is retrieved with the LB_GETITEMDATA message.
    You're right, thanks for the clarification.

  10. #10
    Registered User
    Join Date
    Aug 2004
    Posts
    193
    I guess I dont know constructors, but I'll do some google-ing because I'm a little curious.

    With trial and error I was able to do what you just said before you had posted that.

    Thanks for your help so far and I think this thread is now solved, for now.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with structure and class
    By Bargi in forum C++ Programming
    Replies: 3
    Last Post: 09-25-2007, 02:30 AM
  2. Problem about Creating structure
    By albert3721 in forum C Programming
    Replies: 3
    Last Post: 06-05-2007, 07:33 PM
  3. Structure Array Looping Problem
    By Vitamin_C in forum C++ Programming
    Replies: 2
    Last Post: 12-17-2005, 03:22 PM
  4. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  5. another structure problem
    By hostensteffa in forum C++ Programming
    Replies: 6
    Last Post: 05-06-2002, 03:25 AM