1. Limited time only! Sign up for a free 30min personal tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

C++: initializing 2D arrays

  1. Feb 5, 2009 #1
    I need to initialize the arrays of an object to zero, but when I compile it, it gives me gibberish.

    Here's my code:
     
    Last edited: Feb 6, 2009
  2. jcsd
  3. Feb 5, 2009 #2

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    What do you mean by "gibberish"? Eyeballing it, I see no reason to think this particular code snippet does anything but what it's supposed to do. Could the problem be somewhere else in your code? Try making lots of debugging statements to pin down just where things are going wrong, and precisely what.

    P.S. any particular reason you're not using std::vector?
     
  4. Feb 5, 2009 #3
    It's part of an assignment and the requirements are such that I cannot use vector.
    I mean gibberish as in symbols. I tried printing all of the values out. I even tried setting the value of image[1][1] = 0; in my code, but it wouldn't work. Here's a longer version of my code:


    I'm just using the comment thingies to narrow the part that's causing the problem and so far...it's fine until it hits the initializing part.
     
    Last edited: Feb 6, 2009
  5. Feb 5, 2009 #4

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    Well, the symbols is becuase you're printing unsigned char values. So, the value of the number is interpreted as an ASCII value, and the appropriate ASCII character is printed (e.g. if its value is 65, it would print an uppercase 'A'). If you wanted to print the actual numeric values, you'd have to cast them to an int in the print statement.

    What does getImage look like? Are you sure you're actually getting what you think you're getting?
     
  6. Feb 5, 2009 #5
    I don't know what getImage looks like, because it doesn't actually print out anything, but it doesn't cause a problem. I just tried running it with the getImage function and with it, there are no symbols on the screen, it just prints the indices of the matrix and has a blank. Without running the getImage function, I get the symbols. The loop where it initializes image to zero where it causes the program to terminate unaturally. And as for the symbols showing up, it only shows when it's not image[0]. For image[0] there is a blank.
     
  7. Feb 5, 2009 #6

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    (Note that 0 is the ASCII code for a null character; it usually prints either as nothing, or as a space)

    I'm confused; if your program is terminating unnaturally in the loop in CBin where you set everything to 0, then it shouldn't've gotten to the point where it prints out the indices of the matrix....
     
  8. Feb 5, 2009 #7
    I don't know why either. It prints out the indices of the matrices with the blanks all the way down to "Failed Test 1" but then I get the program termination pop-up.
     
  9. Feb 5, 2009 #8

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    If it printed "Failed test 1", then that means your program actually finished running. Why do you think it crashed in the initialization loop? And what _exactly_ do you mean by "terminated unnaturally"?

    Again, what is getImage? If you're calling it, it might be relevant.
     
  10. Feb 5, 2009 #9
    This is getImage:

    Code (Text):
    void CBin::getImage(unsigned char** destImage)
    {
        for(int i=0;i<height*width;i++)
        {
            destImage[i] = image[i];
        }
    }
    Now it's like terminating randomly. It does go through the initializing function and prints out "Image init!" and since I casted image[j] with int, it's printing zero. So I guess that part may...be okay. It doesn't print "Failed Test 1" now. It terminates right after "Image init!" I thought the delete function may be up to something, so I cut it out and run it again. Nope, it still terminates right after it runs "Image init!"

    EDIT: I think you're right. I cut the for loops out and it terminates after Image2! Right after it runs the getImage function
     
    Last edited: Feb 5, 2009
  11. Feb 5, 2009 #10

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    getImage is definitely wrong.... Your programing is crashing in the destructor, but the error in getImage is the reason.
     
  12. Feb 5, 2009 #11
    could you point out what's wrong with getImage? I'm trying to copy the contents of image into destImage. And also, when I don't run getImage and run the rest of the functions, I find that image is still not properly initialized to zero. Any ideas on why that is?
     
  13. Feb 5, 2009 #12

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    This is one of those things that you look at it for a minute, and then slap your head because you feel silly. But if you haven't figured it out by staring at it.... (or want to see more information after you have figured out the error)

    getImage isn't correctly indexing the arrays; it only gives one index instead of two. And because of that, it's running way out of bounds on the first index, and is doing random things to memory -- something that could cause all sorts of random problems. Furthermore, you've overwritten the pointers in destImage that point to the rows in that array, so test1() is deleting the row you had allocated for bin.image.... and then ~CBin tries to delete that same row again! That causes the crash.
     
  14. Feb 5, 2009 #13
    sorry, I got the first part of what you said about the indices but I didn't get the part where you mentioned delete. ~CBin is trying to delete what Test1() already deleted..?Does that mean one of them is redundant? I am supposed to write a ~CBin function. And the delete in Test1() was given to me to check if my functions run properly. If I have a ~CBin function, does that mean I only need to write: delete[] image; in main()? Also, initializing is still a problem for me, aack.
     
  15. Feb 5, 2009 #14

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    No, it means that one of the side-effects of your error is that you obliterated the pointers to all of the rows in destImage, and replaced them with copies of the pointers to the rows in CBin::image.

    This means that back in test1, after calling getImage, the variable image no longer contains the rows you originally allocated (this is a memory leak; at this point, you can never find that memory again!); it now contains copies of the pointers to the rows you allocated for bin.image.

    So, because of the error in getImage, test1 is not deallocating the rows it allocated earlier; it's deallocating the rows in bin.image. And then later, ~CBin tries to deallocate those same rows.

    Once you fix the error, test1 and ~CBin will now both be deallocating what they think they're deallocating, and all will be well.
     
  16. Feb 5, 2009 #15
    sorry, i think i still may not get what you're saying...I'm changing the pointers of destImage so that they point to image, so how are the pointers of image changing? Right now I've changed getImage to this:



    but i still don't get the initializing/memory leak part...
     
    Last edited: Feb 6, 2009
  17. Feb 5, 2009 #16

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    bin.image is a pointer. During initialization, it's made to point to a 4-long array of unsigned char*. I will use # to indicate uninitialized values. Pictorially, it looks like this:

    bin.image --> # # # #

    Then, you allocated four new arrays (the pointers to which I will call r0, r1, r2, and r3), and assigned them to the four entires of bin.image, so memory looks like this

    bin.image --> r0 r1 r2 r3
    r0 --> # # #
    r1 --> # # #
    r2 --> # # #
    r3 --> # # #

    Of course, you initialized all of those to zeroes:

    bin.image --> r0 r1 r2 r3
    r0 --> 0 0 0
    r1 --> 0 0 0
    r2 --> 0 0 0
    r3 --> 0 0 0


    Then, back in test1, you repeated the process with a variable image. So now, we have 10 dynamically allocated arrays lying about:

    bin.image --> r0 r1 r2 r3
    image --> r4 r5 r6 r7
    r0 --> 0 0 0
    r1 --> 0 0 0
    r2 --> 0 0 0
    r3 --> 0 0 0
    r4 --> # # #
    r5 --> # # #
    r6 --> # # #
    r7 --> # # #

    After invoking your original getImage, everything looks like this

    bin.image --> r0 r1 r2 r3
    image --> r0 r1 r2 r3
    r0 --> 0 0 0
    r1 --> 0 0 0
    r2 --> 0 0 0
    r3 --> 0 0 0
    r4 --> # # #
    r5 --> # # #
    r6 --> # # #
    r7 --> # # #

    (as well as corrupting memory in the 8 memory locations past the end of the image array)
    Note that you've lost the values r4, r5, r6, and r7, and have no way of recreating them. So, the memory they pointed to has been forever lost.

    Then, test1 deallocates the entries of image, and so memory looks like this:

    bin.image --> r0 r1 r2 r3
    image --> r0 r1 r2 r3
    r4 --> # # #
    r5 --> # # #
    r6 --> # # #
    r7 --> # # #

    And then deallocates image.

    bin.image --> r0 r1 r2 r3
    r4 --> # # #
    r5 --> # # #
    r6 --> # # #
    r7 --> # # #


    When you exit test1, bin.~CBin gets called. ~CBin loops through the elements of bin.image and tries to deallocate them. However, r0, r1, r2, and r3 are all nonexistent at this point: bin.image[0] does not point to a valid memory location. So, invoking delete[] bin.image[0] does bad things.
     
  18. Feb 5, 2009 #17
    oh, i get it now...but what am I supposed to do with bin.image?
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook