Discussion:
Large character buffer causes stack overflow
(too old to reply)
Damian Walker
2015-02-08 13:09:58 UTC
Permalink
Hello!

I'm returning to C programming after over a decade doing other things,
and I wanted to give Open Watcom a try. I want to write a simple
retro-game running under DOS, the target an 8088. But I've met a
setback pretty early.

I want to read a ~16k block into memory prior to doing other things with
it. I'm defining a static char array for the purpose, to the exact size
I want (16192 bytes). But whatever I do to get data into it--fread,
memset, setting individual elements--I get a "Stack Overflow!" Here's
the simplest code that creates the problem.

#include <stdio.h>
#include <stdlib.h>

int main() {

/* declarations */
char buffer [16192];

/* fill the buffer */
memset (buffer, 0, 16192);

/* finish the program */
return 0;

}

If I change the buffer size to 80, along with the appropriate parameter
in the call to memset(), the program runs without complaint. A more
complex example used fopen/fread to fill the buffer, with the same
results for 80 and 16192 bytes.

I've read the manual sections about memory models, and I'm using the
default small model. That's supposed to give me 64k of data with a
maximum size of 64k per variable. I can't find anything in the docs to
tell me why I can't have and use a single string of 16192 bytes.

I've ported this example to the old Personal C Compiler, which is my
other option for this project, and the program runs fine. But I'd
prefer to persevere with Watcom, as the documentation is better and it
adheres to ANSI.

Could someone please tell me what I'm doing wrong? Thanks!
--
Damian Walker
Hans-Bernhard Bröker
2015-02-08 15:14:16 UTC
Permalink
Post by Damian Walker
I want to read a ~16k block into memory prior to doing other things with
it. I'm defining a static char array for the purpose,
Actually no, you're not. Which is precisely the problem.
Post by Damian Walker
int main() {
/* declarations */
char buffer [16192];
This array is not static, it's automatic. I.e. it ends up occupying 16
KiB of stack space. No wonder that overflowed your stack.

If you want that array static, you'll have to flag it as such, or move
its definition outside any function, where it'll be of static storage
duration by default. All variables inside a code block default to being
automatic, and I'm sure you knew that once. Looks like that decade of
not doing any c has caught up with you. :-)

The above definition is equivalent to

automatic char buffer [16192];

Now of the very few reserved words in C, "automatic" is by far the least
used, to the point that most people have long since forgotten it even
exists. That's because in all the positions it's even allowed, not
writing anything has the same effect.
Damian Walker
2015-02-08 16:27:10 UTC
Permalink
All variables inside a code block default to being automatic, and I'm
sure you knew that once. Looks like that decade of not doing any c
has caught up with you.
Thank you, Hans-Bernhard!

You credit me with too much knowledge. If this never bit me before, it
was probably because I never had a need for a single buffer this size. :-)

I've prefixed the declaration with the "static" keyword, and I'm no
longer getting the error. Thanks again.
--
Damian Walker
Peter Chapin
2015-02-09 11:52:48 UTC
Permalink
Post by Hans-Bernhard Bröker
The above definition is equivalent to
automatic char buffer [16192];
Now of the very few reserved words in C, "automatic" is by far the least
used, to the point that most people have long since forgotten it even
exists. That's because in all the positions it's even allowed, not
writing anything has the same effect.
Actually the reserved word is 'auto' not 'automatic.' It is being used in
a meaningful way in C++ 2011 to request type inference in declarations.

auto x = 3.14; // x has type double.

This is more useful when the type is complicated to write or even not
possible to write (for example when using lambda expressions).

auto it = my_vector.begin( );

Here 'it' has type std::vector<whatever>::iterator.

Peter
d3x0r
2015-02-13 03:51:18 UTC
Permalink
On Sun, 08 Feb 2015 05:09:58 -0800, Damian Walker =
Post by Damian Walker
Hello!
I'm returning to C programming after over a decade doing other things,=
=
Post by Damian Walker
and I wanted to give Open Watcom a try. I want to write a simple =
retro-game running under DOS, the target an 8088. But I've met a =
setback pretty early.
I want to read a ~16k block into memory prior to doing other things wi=
th =
Post by Damian Walker
it. I'm defining a static char array for the purpose, to the exact si=
ze =
Post by Damian Walker
I want (16192 bytes). But whatever I do to get data into it--fread, =
memset, setting individual elements--I get a "Stack Overflow!" Here's=
=
Post by Damian Walker
the simplest code that creates the problem.
#include <stdio.h>
#include <stdlib.h>
int main() {
/* declarations */
char buffer [16192];
/* fill the buffer */
memset (buffer, 0, 16192);
/* finish the program */
return 0;
}
If I change the buffer size to 80, along with the appropriate paramete=
r =
Post by Damian Walker
in the call to memset(), the program runs without complaint. A more =
complex example used fopen/fread to fill the buffer, with the same =
results for 80 and 16192 bytes.
I've read the manual sections about memory models, and I'm using the =
default small model. That's supposed to give me 64k of data with a =
maximum size of 64k per variable. I can't find anything in the docs t=
o =
Post by Damian Walker
tell me why I can't have and use a single string of 16192 bytes.
I've ported this example to the old Personal C Compiler, which is my =
other option for this project, and the program runs fine. But I'd =
prefer to persevere with Watcom, as the documentation is better and it=
=
Post by Damian Walker
adheres to ANSI.
Could someone please tell me what I'm doing wrong? Thanks!
See the Open Watcom C/C++ User=E2=80=99s Guide for a full description of=
compiler =

options.

Linker options: Description: (wcl?)

k<stack_size> set stack size


wlink

option stack=3Dn

n represents a value. The complete form of n is the following.
[0x]d{d}[k|m]
d represents a decimal digit. If 0x is specified, the string of digits =

represents a hexadecimal
number. If k is specified, the value is multiplied by 1024. If m is =

specified, the value is
multiplied by 1024*1024.

if you really do want a huge stack? I do recommend against, this but I =
=

did have to learn about it to use windows print spooling functions (sele=
ct =

a printer) cause that requires more stack by default than watcom specifi=
es =

by default.


-- =

Using Opera's mail client: http://www.opera.com/mail/

Loading...