11 Replies - 1923 Views - Last Post: 10 May 2010 - 07:01 AM Rate Topic: -----

#1 Guest_Mini*


Reputation:

Help with nested for loops!

Posted 09 May 2010 - 06:53 AM

Hi everyone,

I'm trying to write a program to 'simulate video feedback' so I've chosen to use some 2-dimensional arrays representing a screen/camera etc.

I've got a fairly good idea what I want to do but I keep messing up the loops I'm trying to use and I'm starting to go crazy!

I have a 3x3 array called 'pixel1' that represents a pixel on the screen and I want to fill the 'screen' array with 'pixels'. I'm using some nested for loops for this but every time I've tried, although the code compiles and builds fine, it won't run. I keep getting 'unhandled win32 exception'/'stack overflow' so I think I'm probably calling an array element that doesn't exist but I can't figure out where!

The screen array has 960 columns and 720 rows, the pixels are 3x3 (meaning the screen is 320x240 pixels)

Here are two of my attempts:


	for (i=0; i<240; i=i+1)
	{	
		for(j=0; j<320; j=j+1)
		{
			for(k=0; k<3; k=k+1)
			{
				for(l=0; l<3; l=l+1)
				{
					screen[(i*3)+k][(j*3)+l]=pixel1[k][l];
				}
			}
		}
	}



and also

for (i=0; i<718; i=i+2)
	{	
		for(j=0; j<958; j=j+2)
		{
			screen[i][j]=pixel1[0][0];
			screen[i][j+1]=pixel1[0][1];
			screen[i][j+2]=pixel1[0][2];
			screen[i+1][j]=pixel1[1][0];
			screen[i+1][j+1]=pixel1[1][1];
			screen[i+1][j+2]=pixel1[1][2];
			screen[i+2][j]=pixel1[2][0];
			screen[i+2][j+1]=pixel1[2][1];
			screen[i+2][j+2]=pixel1[2][2];
		}
	}



sorry for the long post! I've just tried everything I can think of so far and I don't see why these loops won't work!

Thanks!

[r]Mod edit: added code tags: :code:

Is This A Good Question/Topic? 0

Replies To: Help with nested for loops!

#2 joesyuh   User is offline

  • D.I.C Head

Reputation: 36
  • View blog
  • Posts: 175
  • Joined: 30-September 08

Re: Help with nested for loops!

Posted 09 May 2010 - 07:04 AM

Could you edit your post and use the code tags provided by the text editor. They are the "<>" symbols above the text box. :) Just makes the code easier to read.
Was This Post Helpful? 0
  • +
  • -

#3 japanir   User is offline

  • jaVanir
  • member icon

Reputation: 1014
  • View blog
  • Posts: 3,025
  • Joined: 20-August 09

Re: Help with nested for loops!

Posted 09 May 2010 - 07:10 AM

Also, would be helpful if you posted the full code. (especiaaly declaration of the arrays, variables etc.)
Was This Post Helpful? 0
  • +
  • -

#4 NickDMax   User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2255
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: Help with nested for loops!

Posted 09 May 2010 - 07:18 AM

The code you have here should not cause a stack overflow... though your definition of screen might.

320 * 240 * 3 * 3 = 691200 -- on a 32bit machine that is 2764800 bytes which is 2.64Mb... stack space is normally limited to about 2Mb under windows... so you may want to change "screen" to dynamic memory.

Whenever you deal with nested loops keep multiplication in mind. Even little numbers grow very fast.
Was This Post Helpful? 0
  • +
  • -

#5 Guest_mini*


Reputation:

Re: Help with nested for loops!

Posted 09 May 2010 - 08:02 AM

Sorry for the lack of code tags and thanks for the help/fast responses!

@NickDMax - I know very little about different types of memory so I had no idea that could be a problem! I've never used dynamic memory before so I'll go and hunt for some info on the web and see if it sorts the problem. Thanks again!
Was This Post Helpful? 0

#6 Guest_mini*


Reputation:

Re: Help with nested for loops!

Posted 09 May 2010 - 08:33 AM

Sorry for the double post but I just tried reducing the size of screen to see if it made any difference - I took it down to 12 columns and 9 rows (4 pixels by 3 pixels) and still got the same error. I'm really not sure what I'm doing wrong!
Was This Post Helpful? 0

#7 NickDMax   User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2255
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: Help with nested for loops!

Posted 09 May 2010 - 09:11 AM

Well to show you that it is not a problem with the nested loops here is an example:
#include <iostream>

using namespace std;

const int height = 240;
const int width = 320;
const int pixelHeight = 3;
const int pixelWidth = 3;


int main() {
    int* screen = new int[height*width*pixelHeight*pixelWidth];
    int lineWidth = pixelWidth*width;
    for (int y = 0; y < 240; ++y) {
        for (int x = 0; x < 320; ++x) {
            for (int py = 0; py < 3; ++py) {
                for (int px = 0; px < 3; ++px) {
                    screen[(x*pixelWidth+px) + (lineWidth*(y*pixelHeight+py))] = px+pixelWidth*py;
                }
            }
        }
    }
    for(int y = 0; y < pixelHeight*height; ++y) {
        for(int x = 0; x < pixelWidth*width; ++x) {
            cout << screen[x+lineWidth*y];
        }
        cout << endl;
    }
    delete[] screen;    

    return 0;
}


note to really view the output of this little program you should probably redirect output to a file.

it generates something like this:
012012012012012012...
345345345345345345...
678678678678678678...
012012012012012012...
345345345345345345...
678678678678678678...
...


So what I am saying is that your problem is probably somewhere else. without seeing the code I can't tell... but the nested loop will not cause a stack overflow.
Was This Post Helpful? 0
  • +
  • -

#8 Guest_mini*


Reputation:

Re: Help with nested for loops!

Posted 09 May 2010 - 09:59 AM

Thank you so much for the example, it was really helpful!
I cut everything else out of my code apart from the loops, I made the screen size smaller and still no luck! Is it possible that I'm calling an array element that doesn't exist? I've looked at the loops a few times to be sure but I may still be missing something!

If it helps here's the code in full (I know I've included more libraries than I need, it's just to stop me forgetting them when I eventually write the rest of it)

#include <cmath>
#include <fstream>
#include <iostream>
using namespace std;

int main (void)
{
	int pixel1[3][3] = {{0,0,0}, {1, 1, 0}, {1, 1, 0}};	
	double screen[720][960];
	int i, j, k, l;


	for (i=0; i<240; i=i+1)
	{	
		for(j=0; j<320; j=j+1)
		{
			for(k=0; k<3; k=k+1)
			{
				for(l=0; l<3; l=l+1)
				{
					screen[(i*3)+k][(j*3)+l]=pixel1[k][l];
				}
			}
		}
	}

return 0;
}



and also

#include <cmath>
#include <fstream>
#include <iostream>
using namespace std;

int main (void)
{
	int pixel1[3][3] = {{0,0,0}, {1, 1, 0}, {1, 1, 0}};	
	double screen[720][960];
	int i, j, k, l;


for (i=0; i<718; i=i+2)
	{	
		for(j=0; j<958; j=j+2)
		{
			screen[i][j]=pixel1[0][0];
			screen[i][j+1]=pixel1[0][1];
			screen[i][j+2]=pixel1[0][2];
			screen[i+1][j]=pixel1[1][0];
			screen[i+1][j+1]=pixel1[1][1];
			screen[i+1][j+2]=pixel1[1][2];
			screen[i+2][j]=pixel1[2][0];
			screen[i+2][j+1]=pixel1[2][1];
			screen[i+2][j+2]=pixel1[2][2];
		}
	}

return 0;
}




thanks again, I really appreciate all your help.
Was This Post Helpful? 0

#9 NickDMax   User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2255
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: Help with nested for loops!

Posted 09 May 2010 - 11:54 AM

a double is generally about 8 bytes... so 8 * 720 * 960 = 5529600 which is about 5.28Mb.. so you did NOT make the array much smaller, you made it bigger.

Basically though you just need to use dynamic memory. Unfortunately using dynamic memory with 2D arrays can be a bit tricky. However if the dimentions of your 2D array are not going to change then you can do something like this:
#include <cmath>
#include <fstream>
#include <iostream>
using namespace std;

typedef double Screen[720][960];


int main (void) {
    int pixel1[3][3] = {{0, 0, 0}, {1, 1, 0}, {1, 1, 0}};
    Screen& screen = *((Screen*)(new double[sizeof(Screen)]));
    int i, j, k, l;
    
    cout << sizeof(Screen) << endl;
    for (i = 0; i < 240; ++i) {
        for (j = 0; j < 320; ++j) {
            for (k = 0; k < 3; ++k) {
                for (l = 0; l < 3; ++l) {
                    screen[(i*3)+k][((j*3)+l)] = pixel1[k][l];
                }
            }
        }
    }
    delete[] &screen;

    return 0;
}


This is a bit awkward and it may be a little easier to just use a 1D array and a little math (as I did in my last example). But here is the explanation of the parts:

First is the typedef: typedef double Screen[720][960]; -- you cannot allocate this array on the stack as it is too large, but you still want to be able to use it as a 2D array, so we need a reference to that type.

Next we need to declare an instance of screen that we can use like a normal 2D array. new will return a pointer. But if we accessed screen as a pointer the syntax with be a bit strange:(*screen)[x][y] so to keep the syntax for accessing the array simple I used a reference.

So we need to create enough space -- now our typedef is not a proper type, it is only an "alias" for double[720][960] so if we tried to use:
[il]new Screen;[il] we would get an error because new can not allocate 2D arrays (at least directly like this) -- so we just need to allocate enough memory and then cast it to a pointer to Screen. Thus I used sizeof() to determine how much memory I needed (you could also use double[720*960]).


So new allocates a block of memory on the heap. Then we assign that to a reference to a 2D array that we can now use (as a 2D array).


NORMALLY though, the way to deal with dynamic 2D arrays is to use math to determine the element you need to access.

index = x + y * width

is the normal formula.
Was This Post Helpful? 0
  • +
  • -

#10 Guest_mini*


Reputation:

Re: Help with nested for loops!

Posted 10 May 2010 - 06:06 AM

Thank you so much for your detailed example!

I realise using the 2D arrays is a little cumbersome but it really helps me to visualise what's going on in the program (since eventually it's meant to be a model of a real life situation!).

Your explanation of the syntax used was great - I understand dynamic memory a lot better now! One final question though, with the line
delete[] &screen; 
- would this go at the very end of the program if I was to add further loops that involved changing elements of the screen?
Was This Post Helpful? 0

#11 NickDMax   User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2255
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: Help with nested for loops!

Posted 10 May 2010 - 06:34 AM

The delete happens when you are done with the memory. That is a big block of memory and when you are done with it you will want to return it to the OS for other uses. So you can put it at the end of the program or just use it when you are done with the memory for now.

BTW the syntax for the delete here is a tiny bit unusual. The delete operator takes a pointer to the allocated memory (the address of the allocated memory) -- the same pointer/address that was returned by the new operator. Since screen is a reference we need to use the "address of" operator to get the address of the memory allocated by new.


I mention this because normally the syntax would be like the example first example I gave.
Was This Post Helpful? 0
  • +
  • -

#12 NickDMax   User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2255
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: Help with nested for loops!

Posted 10 May 2010 - 07:01 AM

Since you are in C++ and you have long term plans you might want to think about making an object to manage your array rather than using direct memory allocation like that.

There are some big advantages to doing things this way. #1 the compiler can maintain scope and can construct/deconstruct objects for you -- which can be far easier to manage than creating your own memory management scheme for large arrays.

#2 you can create an easy to use syntax free of the constraint that the array size be static. The above example will only work for the particular dimensions we set. So if you wanted to create a 3x3 array in a similar fashion you would have to create a new typedef and so forth... if you wanted to create an NxM array you would need to know N and M at COMPILE time, not at run time. So for example your user can't pick dimensions.

But with object you could have a function like: screen.pixel(5,5) = 8;.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1