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

  • Comp Sci
  • Thread starter subwaybusker
  • Start date
  • Tags
    2d Arrays
In summary: Could you elaborate?Basically, what you're doing is overwriting the memory locations where the arrays were initialized to zero. If you're not careful, this can cause your program to crash.
  • #1
subwaybusker
51
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
  • #2
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?
 
  • #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:
  • #4
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?
 
  • #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.
 
  • #6
(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...
 
  • #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.
 
  • #8
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.
 
  • #9
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?
 

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

1. How do you declare and initialize a 2D array in C++?

In C++, a 2D array can be declared and initialized using the following syntax:
data_type array_name[row_size][column_size] = { {value1, value2, ...}, {value1, value2, ...}, ... };
The data_type refers to the type of data that will be stored in the array, while row_size and column_size indicate the dimensions of the array. The values enclosed in curly braces represent the elements of the array, with each inner curly brace representing a row of elements.

2. How do you dynamically allocate memory for a 2D array in C++?

To dynamically allocate memory for a 2D array in C++, you can use the new operator. The syntax is as follows:
data_type **array_name = new data_type*[row_size];
for (int i = 0; i < row_size; i++) {
  array_name[i] = new data_type[column_size];
}

This will create a 2D array with row_size rows and column_size columns, and each element can be accessed using the index notation (array_name[row_index][column_index]). Don't forget to deallocate the memory using delete[] when you're done using the array.

3. Can you initialize a 2D array with user input in C++?

Yes, you can initialize a 2D array with user input in C++. You can use nested for loops to traverse through the array and use cin to get user input for each element. For example:
for (int i = 0; i < row_size; i++) {
  for (int j = 0; j < column_size; j++) {
    cin >> array_name[i][j];
  }
}

Note that the array must be declared and initialized before using user input to populate its elements.

4. How do you access and modify elements in a 2D array in C++?

To access and modify elements in a 2D array in C++, you can use the index notation (array_name[row_index][column_index]). For example, to access the element in the first row and second column, you would use array_name[0][1]. To modify the value of an element, simply assign a new value to it using the assignment operator (=). For example, array_name[0][1] = 10; will change the value of the element to 10.

5. Can a 2D array have different data types in C++?

No, a 2D array in C++ must have the same data type for all of its elements. However, you can create a 2D array of structures, where each structure can contain different data types. For example:
struct Person {
  string name;
  int age;
};
Person people[2][3]; // creates a 2D array of Person structures with 2 rows and 3 columns

In this case, each element in the array is a structure that contains a string and an integer.

Similar threads

  • Engineering and Comp Sci Homework Help
Replies
3
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
3
Views
788
  • Engineering and Comp Sci Homework Help
Replies
7
Views
2K
  • Engineering and Comp Sci Homework Help
2
Replies
43
Views
4K
  • Engineering and Comp Sci Homework Help
Replies
21
Views
2K
Replies
1
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
5
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
2
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
18
Views
1K
Back
Top