This function reads a terrain map which is just a grayscale bitmap of 131,072 by 1 pixel which contains height data. The height data and stuff run without problems, but I'm getting this strange "stack overflow" error when I expanded this function to draw a monochrome bitmap that lets me get a look at what the lay of the land actually looks like in a simple 2D side view instead of looking at shades of gray representing slope angles.

else if (ImageTerrainHeight > ImageTargetHeight+26.4) // if above the next step, it should be all white // causes stack overflow
{
TerrainPreviewData[ImageBaseArrayIndex] = 255; // all 8 pixels are white
}

When the function gets to the first and second if statements in the "while (ByteBlock < 16)" part, I get an unhandled exception notice saying of stack overflow. I don't know about the else though. The other two instructions work just fine and there's no infinite loop encountered. The other while loop where I fill the rest of the array's values to 5, near the bottom, works just fine, but when I try writing this data, I get that stack overflow case again and it's not writing any of the image data. It's writing the file head and info head just fine and I can see it in my hex editor as I expected.

What is a "stack overflow" error? What is a "stack"? How can I fix this problem? I've had much bigger write amounts (250 MB) done numerous times and not once did I get a problem. I'm getting it with just 2 MB. This is only intended to run on my computer so compatibility with other computers is not necessary. The program has windows.h included at the top and everything in this function uses local variables. I spent some time to find the areas causing the problem and it's only these 3 areas. With the if's and else's used in the "ByteBlock < 16" loop commented out along with the write of 2 MB, the function runs just fine without any problems and behaves as intended for what isn't commented out.

04-28-2007

zacs7

Your going past memory that belongs to you, (your trying to read/write someone elses memory). Ie If you have an array allocated on the stack that is 5 bytes long, your probably trying to access the 6th byte or something like that.

Id say in the last loop that 'ImageBaseArrayIndex' points to an element out-of-bounds in 'TerrainPreviewData'.

04-28-2007

ulillillia

That doesn't seem to be the case. The while loop works just fine, but if I try to write the contents, which writes to disk, I get this error. The first, long loop only goes out to 3500 for the ArrayIndex as that's how far I've gone in my terrain. This puts ImageBaseArrayIndex below even 60,000. The array with the data in it has 2 million values possible so array overflow is not the problem.

I tried setting the write amount to just 2000 and I still get the stack overflow. The array's length is 2097152 (which is 2^21), so I can almost certainly rule out array overflow. Array overflow would cause "error writing to memory at location xxx" instead of just "stack overflow". Heh, I even set the amount to write as just 1 and I still get stack overflow!

Why not just dump the entire struct to disc? Rather than writting each element, it's a lot less code and it's easier to understand.

04-28-2007

brewbuck

The stack is no place for a two megabyte object.

04-28-2007

MacGyver

Might I add that this is kind of a large function, that large functions do not promote readability, and therefore do not assist in either the debugging or maintaining areas of a software's lifecycle.

04-29-2007

Salem

> Why not just dump the entire struct to disc?
Research previous posts on padding and alignment. There is no reason to believe that the way the compiler organises a struct in memory will match that of the file format.

If you want true portability (solves the endian problem as well), then you have to read and write the file one byte at a time.

> What is a "stack overflow" error?
What it means.

> What is a "stack"?
That's a very odd question for someone writing code to ask. It's that thing used to manage local variables, function calls and returns etc.

> How can I fix this problem?
Remove those big dumb arrays from your function and allocate them elsewhere.
- dynamically allocate them is one way
- prefix them with the word 'static' is another (perhaps not so good, but dead easy)

> I'm getting it with just 2 MB.
There is a way to change the default stack size (look in the linker options).

Also, the selection of color indexes seems pretty strange. If you had chosen them to all be consecutive, you could have done this with a simple array of ints, used the terrain color to index into this array (after appropriate bounds checking).

04-29-2007

ulillillia

Basically, if I'm understanding this right, I cannot have a 2 MB local array? In my case where I got a 250 MB array to work without problems, the array was global. I don't know how to dynamically change the size of an array, whether local or global (that is, going from myarray[131072] to myarray[192000] or something else). As to writing the structures, I didn't know it was possible to write the full structure in one write statement.

The reason for the selection of colors is for the appearance and contrast. It would otherwise have a step value of 8 (going from 0 to 8, 16, 24, etc.) and it's very difficult to see the difference in the colors. The steps of 16 are much easier to see. The X (horizontal) change remains constant for the terrain and the Y (vertical) is adjusted to get as close as possible to a multiple of 5&#176; and goes up to an 80&#176; slope.

04-29-2007

zacs7

nevermind about writing the structure in one statement, I silly to suggest that - as pointed out by Salem.

Look-up realloc() that should give you a hint ;)

04-29-2007

whiteflags

Quote:

Originally Posted by ulillillia

Basically, if I'm understanding this right, I cannot have a 2 MB local array? In my case where I got a 250 MB array to work without problems, the array was global. I don't know how to dynamically change the size of an array, whether local or global (that is, going from myarray[131072] to myarray[192000] or something else). As to writing the structures, I didn't know it was possible to write the full structure in one write statement.

These sorts of questions are asked all the time here, so I recommend using our best kept secret (apparently). The search page.

04-29-2007

brewbuck

Quote:

Originally Posted by ulillillia

The reason for the selection of colors is for the appearance and contrast.

But this is indexed color, is it not? You can arrange the palette however you want. You could arrange it so that all the colors you are using are numbered incrementally from 0..n.

04-29-2007

ulillillia

The terrain map that is read (which is 131072x1 pixels in size) is actually 8-bit grayscale. The file that is written (which is 131072x128 but later to be resized) is 1-bit monochrome. By using a global array instead, then fixing bugs unrelated to the stack overflow, I've got everything working and it looks nice. If only MSPaint actually worked properly for images over 32,768 pixels long, I wouldn't need to wait 20+ seconds for The GIMP to load the 2 MB file. What I'm seeing in my output, which is intended to help visualize what the terrain actually looks like, is what I expected to see.