Really strange, unexpected values from allocated variables

This is a discussion on Really strange, unexpected values from allocated variables within the Windows Programming forums, part of the Platform Specific Boards category; Okay, I've been able to narrow down the problem to a certain point in a function called when the user ...

  1. #1
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256

    Really strange, unexpected values from allocated variables

    Okay, I've been able to narrow down the problem to a certain point in a function called when the user presses the Generate Button (I've included a screenshot of my program). Here's the function in its entirety. And I've commented the lines that I was able to narrow it down to.
    Code:
    void GenerateNumbers(HWND hwnd)
     {
      int index = 0;
      int index2 = 0;
    
      int result;
      int number = GetDlgItemInt(hwnd, IDC_INPUT_NUMBER, NULL, FALSE);
      int min = GetDlgItemInt(hwnd, IDC_INPUT_MINIMUM, NULL, FALSE);
      int max = GetDlgItemInt(hwnd, IDC_INPUT_MAXIMUM, NULL, FALSE);
      int* generated;
      generated = GlobalAlloc(GPTR, number);
      if(generated == NULL)
        MessageBox(hwnd, "Failure allocating generated", "Error:", MB_ICONERROR | MB_OK);
      int outputsize = log10(max) + 2;
      char* output;
      output = GlobalAlloc(GPTR, outputsize);
      if(output == NULL)
        MessageBox(hwnd, "Failure allocating output", "Error:", MB_ICONERROR | MB_OK);
      InitCharArray(outputsize, output, 0);
    
      for(index = 0; index < number; index = index)
       {
        time(&currenttime);
        seed *= (unsigned int)currenttime + seed + index + 1;
        if(seed == 0)
         {
          seed += index + 1;
         }
        srand((unsigned int)(seed));
        result = rand() % (max - min + 1) + min;
        if(NoDuplicates == TRUE)
         {
          for(index2 = 0; index2 < index; ++index2)
           {
            if(result == generated[index2])
              break;
           }
         }
        if(result == generated[index2])
          continue;
        generated[index] = result;
    /*****Between here*****/
        itoa(result, output, 10);
    /*******and here*******/
        SendDlgItemMessage(hwnd, IDC_OUTPUT, LB_ADDSTRING, 0, (LPARAM)output);
        ++index;
       }
      GlobalFree(generated);
      GlobalFree(output);
     }
    Basically, when I have the program generate five random numbers, on the first run through, only, the value of generated[index] when index is 4 changes somewhere in the line indicated above. After that, it stays the same when index is 4. But, even though that stays the same, if I keep on pressing Generate, every so often, I will get something similar to the following output from my debug window (I've erased all debug code from the above code).
    Code:
    generated[index] = 
    result = 5
    generated[index] = 0
    output = 53
    When the output I would expect would be
    Code:
    generated[index] = 5
    result = 5
    generated[index] = 5
    output = 53
    I don't know if this is simply a glitch that occurs when getting the value to my debug window and the value of generated[index] is actually just fine, But I don't think so, since it only occurs sometimes.

    Does anyone have any ideas what's going on?
    Attached Images Attached Images  
    Last edited by Jaken Veina; 04-16-2005 at 04:48 PM.

  2. #2
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,451
    > int outputsize = log10(max) + 2;
    > char* output;
    > output = GlobalAlloc(GPTR, outputsize);
    Think about what you're doing here. There isn't that much variation to really justify this level of detail, and its way more expensive to do than say
    char output[20];

    > srand((unsigned int)(seed));
    Read the FAQ's.
    Calling srand() more than once is usually bad, and calling it inside the same loop as rand() is simply a waste of time (even more so if you're trying to eliminate duplicates).
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  3. #3
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256
    I have read the FAQs, I don't remember reading anything about it being bad to call it more than once. Besides, how else would I be able to get different numbers from rand() without changing the seed?

    But you do have a very good point with the allocation of output. After all, the way I have the Dialog drawn, I know none of the values they enter can be more than eight digits. Too bad I can't do this with generated, unless I declared it as an array with 99999999 elements.

    EDIT:............................I love you. All the errors are completely gone. ^_^ As far as I can tell, at least. I'll keep checking for others.
    Last edited by Jaken Veina; 04-16-2005 at 05:25 PM.

  4. #4
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    [edit]
    I deleted this post thinking that I had been beaten and the problem had been solved. Fortunately, the post was still in my clipboard buffer so I can repost.

    >> All the errors are completely gone. <<

    I think you mean, "All the errors are completely hidden.". :-)
    [/edit]

    Hi. Firstly, GlobalAlloc is a depreciated Windows function. If your program is C++, you could use new. If your program is C you could use malloc.
    Code:
      int* generated;
      generated = GlobalAlloc(GPTR, number);
    GlobalAlloc and malloc take the size of memory in chars (bytes). Therefore, if you are not allocating chars you must multiply by the size you need for each element:
    Code:
      int* generated;
      generated = malloc(number * sizeof(*generated));
    which is equivalent to:
    Code:
      int* generated;
      generated = malloc(number * sizeof(int));
    In C++, the new operator takes care of this for us:
    Code:
      int* generated;
      generated = new int[number];
    A int on Win32 is 4 bytes. Since you were only allocating one byte for each int you were seeing the weird behaviour of a buffer overrun.

  5. #5
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,451
    Perhaps you need to read the manual pages for rand() and srand() again.

    > Besides, how else would I be able to get different numbers from rand() without changing the seed?
    You change the seed ONCE when the program starts, then call rand() as many times as you feel is necessary.

    http://faq.cprogramming.com/cgi-bin/...&id=1043284385
    "The srand() function is called only once during a programs execution."
    It's even in bold, how could you miss it.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  6. #6
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256
    *smacks head* How in the name of God could I have forgotten that? ARGH!!!! I knew that too!!! I spent weeks writing a program using those every single day! BLARGH!

    Well, I had a whole bunch more errors I found. Although, I had gotten them bfore, I just wasn't concentrating on them. But considering what you just pointed out, they make perfect sense now. I'll change that right now and see what happens.

    Just as I thought. Everything seems fine now. Finally, I can get back to actually progressing. ^_^ Thanks, both of you. If anything else comes up that i can't figure out, I'll post it here.

  7. #7
    Work in Progress..... Jaken Veina's Avatar
    Join Date
    Mar 2005
    Location
    Missouri. Go Imos Pizza!
    Posts
    256
    (In response to Salem's latest post)

    *smacks head again* Of course. Srand() stores the address of seed, not the vaule, like I thought. Therefore if the seed changes, it is automatically compensated for. I only read the tutorial on random numbers, not the FAQ sectoin. Ahh well, thanks again. I'll change that right away.
    Last edited by Jaken Veina; 04-16-2005 at 05:46 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. fread returns strange values
    By seaking1 in forum C Programming
    Replies: 6
    Last Post: 04-30-2009, 02:10 AM
  2. Replies: 4
    Last Post: 03-07-2009, 08:07 AM
  3. Strange results using dnsapi and windns
    By Niara in forum Networking/Device Communication
    Replies: 3
    Last Post: 08-13-2005, 10:21 AM
  4. functions to return 2 variables?
    By tim in forum C Programming
    Replies: 5
    Last Post: 02-18-2002, 01:39 PM
  5. assign values to charechter variables
    By simhap in forum C++ Programming
    Replies: 5
    Last Post: 10-07-2001, 07:55 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21