How can I initialize 2D arrays in C++ to avoid gibberish output?

  • Context: Comp Sci 
  • Thread starter Thread starter subwaybusker
  • Start date Start date
  • Tags Tags
    2d Arrays
Click For Summary

Discussion Overview

The discussion revolves around the initialization of 2D arrays in C++ and the issues related to unexpected output, specifically "gibberish" characters when printing values. Participants explore the potential causes of program termination and memory management issues, particularly in the context of an assignment that prohibits the use of std::vector.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Homework-related
  • Mathematical reasoning

Main Points Raised

  • One participant reports gibberish output when printing values from a 2D array, suggesting a need for proper initialization.
  • Another participant questions the definition of "gibberish" and suggests debugging to identify the source of the problem.
  • It is noted that printing unsigned char values directly may lead to unexpected ASCII character outputs.
  • Concerns are raised about the program terminating unexpectedly during the initialization loop, with participants seeking clarification on what "terminated unnaturally" means.
  • A participant describes the behavior of the getImage function, which is suspected to be causing issues related to memory management.
  • There is a discussion about the implications of pointer management and memory leaks resulting from incorrect handling of dynamic arrays.
  • One participant expresses confusion about the relationship between the getImage function and the destructor, indicating a lack of clarity on memory allocation and deallocation responsibilities.
  • Another participant provides a detailed explanation of how pointers are affected during the execution of the getImage function, illustrating the potential for memory leaks and corruption.

Areas of Agreement / Disagreement

Participants express varying levels of understanding regarding the initialization of arrays and the implications of pointer management. There is no consensus on the exact cause of the issues being faced, and multiple competing views on how to resolve the problems remain.

Contextual Notes

Limitations include unclear assumptions about the behavior of the getImage function and its impact on memory management. The discussion highlights unresolved issues related to the initialization of the 2D array and the handling of dynamic memory.

Who May Find This Useful

Readers interested in C++ programming, particularly those dealing with dynamic memory allocation, array initialization, and debugging techniques in the context of assignments or projects.

subwaybusker
Messages
47
Reaction score
0
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:
Physics news on Phys.org
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?
 
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:
Well, the symbols is because 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?
 
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.
 
(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...
 
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.
 
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.
 
This is getImage:

Code:
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:
  • #10
getImage is definitely wrong... Your programing is crashing in the destructor, but the error in getImage is the reason.
 
  • #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?
 
  • #12
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.
 
  • #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.
 
  • #14
subwaybusker said:
Does that mean one of them is redundant?
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.
 
  • #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:
  • #16
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.
 
  • #17
oh, i get it now...but what am I supposed to do with bin.image?
 

Similar threads

  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 3 ·
Replies
3
Views
1K
  • · Replies 21 ·
Replies
21
Views
3K
Replies
7
Views
3K
Replies
43
Views
5K
Replies
1
Views
2K
  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 17 ·
Replies
17
Views
3K
  • · Replies 1 ·
Replies
1
Views
2K