Novice array size

F

Francogrex

Why this below crashes (when the executable is run)? Is there a way to
avoid it? When I replace n=700-1 by n=100-1 it works but I really need
large values of n how can I deal with it? Thanks

#include <stdio.h>
int main()
{
int i, j, n= 700-1;
int size=(n*(n-1));
double tabP [size] [3];
for(j=0;j< 3;j++)
{
for (i=0;i<size;i++)
{
tabP [j]=0.0;
printf("%f",tabP [j]);
}
}
 
K

Kojak

Le Tue, 3 Mar 2009 23:39:04 -0800 (PST),
Francogrex a écrit :
Why this below crashes (when the executable is run)? Is there a way to
avoid it? When I replace n=700-1 by n=100-1 it works but I really need
large values of n how can I deal with it? Thanks

#include <stdio.h>
int main()
{
int i, j, n= 700-1;
int size=(n*(n-1));
double tabP [size] [3];
for(j=0;j< 3;j++)
{
for (i=0;i<size;i++)
{
tabP [j]=0.0;
printf("%f",tabP [j]);
}
}


No memory reserved for tabP!
This version should work:

------8<------8<------8<------8<------8<------8<------8<------8<
#include <stdio.h>

#define SIZE 487902

int main (void)
{
int i, j;
double tabP[SIZE][3];

for (j = 0; j < 3; j++) {
for (i = 0; i < SIZE; i++) {
tabP[j] = 0.0;
printf ("%f", tabP[j]);
}
}
return 0;
}
------8<------8<------8<------8<------8<------8<------8<------8<
 
S

sathya

Why this below crashes (when the executable is run)? Is there a way to
avoid it? When I replace n=700-1 by n=100-1 it works but I really need
large values of n how can I deal with it? Thanks

#include <stdio.h>
int main()
{
  int i, j, n= 700-1;
  int size=(n*(n-1));
  double tabP [size] [3];
  for(j=0;j< 3;j++)
    {
      for (i=0;i<size;i++)
        {
          tabP [j]=0.0;
        printf("%f",tabP [j]);
        }
    }


please look at the line number

Try this steps and find out
----------------------------

1. Enable core-dump
ulimit -c unlimited
2. ulimit -a
3. gcc -g code.c -o excecutble
4. gdb executble core

-------------------------------------------------------
 
F

Francogrex

Hello. Please post the output of the following program:

---------------------------------------------------------------------------
#include <stdio.h>
#include <limits.h>

int main(void)
{
    printf("%d\n", INT_MAX);
    return 0;

}

Hi, it's 2147483647. So i assume bigger than what is needed for my
program? Someone suggested to use #define size before the main
program, but in many cases the n is not known yet (it will depend on
the result calculated by another function).
 
R

Richard Tobin

Why this below crashes (when the executable is run)? Is there a way to
avoid it? When I replace n=700-1 by n=100-1 it works but I really need
large values of n how can I deal with it? Thanks
int size=(n*(n-1));
double tabP [size] [3];

Your array has 1463706 elements. If double is 8 bytes, that's
11709648 bytes. The array is a local variable, and quite likely your
stack is limited to a size smaller than that. There's probably
some way to increase the limit (e.g. ulimit -s on unix with bash),
or you could make the array static or allocate it with malloc().

-- Richard
 
F

Francogrex

No memory reserved for tabP!
This version should work:

------8<------8<------8<------8<------8<------8<------8<------8<
#include <stdio.h>

#define SIZE 487902

int main (void)
{
        int i, j;
        double tabP[SIZE][3];

        for (j = 0; j < 3; j++) {
                for (i = 0; i < SIZE; i++) {
                        tabP[j] = 0.0;
                        printf ("%f", tabP[j]);
                }
        }
        return 0;}

------8<------8<------8<------8<------8<------8<------8<------8<


sorry but even with this the executable is crashing. I am on Windows
XP 32bit OS using gcc compiler (MinGW 5.14nthe most recent).
 
K

Kojak

Le Wed, 4 Mar 2009 01:36:32 -0800 (PST),
Francogrex a écrit :
[...] Someone suggested to use #define size before the main
program, but in many cases the n is not known yet (it will depend on
the result calculated by another function).

In this case you must allocate memory dynamically.
 
M

Mark Wooding

Francogrex said:
Why this below crashes (when the executable is run)? Is there a way to
avoid it?

Looks to me like you're blowing the stack (or wherever it is that
objects with automatic storage duration get allocated).
When I replace n=700-1 by n=100-1 it works but I really need large
values of n how can I deal with it? Thanks [...]
int size=(n*(n-1));
double tabP [size] [3];

If sizeof(double) is 8, then this is 11MB. On my system here, the stack
is limited by default to 8MB, but I can raise the limit by typing

ulimit -s 65536

If I do this then your program doesn't crash any more.

Your platform might have a different way of adjusting the stack limit
(if indeed it has a stack). Of course, having to do this before running
the program is unpleasant, and messing with system limits in the program
is nonportable.

I'd suggest that your best bet is to use malloc and free to manage the
storage for large arrays rather than allocating them automatically as
you've done.

-- [mdw]
 
K

Kojak

Le Wed, 4 Mar 2009 01:44:47 -0800 (PST),
Francogrex a écrit :
No memory reserved for tabP!
This version should work:
[... code sniped ...]

sorry but even with this the executable is crashing. I am on Windows
XP 32bit OS using gcc compiler (MinGW 5.14nthe most recent).

I don't know Window nor MinGW, sorry. That said, it's quite strange!
Probably some memory, or limitation issue...

Well, try this one and tell me what happens.

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

int main (void)
{
int i, j, n = 700 - 1;
int size = (n * (n - 1));
double (*tabP)[3];

if ((tabP = malloc (3 * size * sizeof (double))) == NULL) {
printf ("Guess what?\n");
return EXIT_FAILURE;
}

for (j = 0; j < 3; j++) {
for (i = 0; i < size; i++) {
tabP[j] = 0.0;
printf ("%f", tabP[j]);
}
}

return EXIT_SUCCESS;
}
------8<------8<------8<------8<------8<------8<------8<------8<
 
F

Francogrex

I don't know Window nor MinGW, sorry. That said, it's quite strange!
Probably some memory, or limitation issue...

Well, try this one and tell me what happens.

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

int main (void)
{
        int i, j, n = 700 - 1;
        int size = (n * (n - 1));
        double (*tabP)[3];

        if ((tabP = malloc (3 * size * sizeof (double))) == NULL) {
                printf ("Guess what?\n");
                return EXIT_FAILURE;
        }

        for (j = 0; j < 3; j++) {
                for (i = 0; i < size; i++) {
                        tabP[j] = 0.0;
                        printf ("%f", tabP[j]);
                }
        }

        return EXIT_SUCCESS;}

------8<------8<------8<------8<------8<------8<------8<------8<


OK THIS WORKS! But how come? I'll study it to see.
 
B

Ben Bacarisse

Kojak said:
Well, try this one and tell me what happens.

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

int main (void)
{
int i, j, n = 700 - 1;
int size = (n * (n - 1));
double (*tabP)[3];

if ((tabP = malloc (3 * size * sizeof (double))) == NULL) {

The oft-quoted idiom for malloc avoids duplicating the 3:

tabP = malloc(size * sizeof *tabP);

This idiom is good because the allocation continues to work when the
type of tabP changes. That may not happen here (if 3 is rooted in the
problem) but for 2D arrays in general, it is very valuable.
 
G

Guest

Le Tue, 3 Mar 2009 23:39:04 -0800 (PST),
Francogrex a écrit :
Why this below crashes (when the executable is run)? Is there a way to
avoid it? When I replace n=700-1 by n=100-1 it works but I really need
large values of n how can I deal with it? Thanks
#include <stdio.h>
int main()
{
  int i, j, n= 700-1;
  int size=(n*(n-1));
  double tabP [size] [3];

memory allocated for tabP (which isn't a pointeer as the name might
indicate)
  for(j=0;j< 3;j++)
    {
      for (i=0;i<size;i++)
   {
     tabP [j]=0.0;
   printf("%f",tabP [j]);
   }
    }


No memory reserved for tabP!


I beg to differ

<snip>
 
K

Kojak

Le Wed, 04 Mar 2009 12:53:55 +0000,
Ben Bacarisse a écrit :
Kojak said:
double (*tabP)[3];
if ((tabP = malloc (3 * size * sizeof (double))) == NULL) {

The oft-quoted idiom for malloc avoids duplicating the 3:

tabP = malloc(size * sizeof *tabP);

This idiom is good because the allocation continues to work when the
type of tabP changes. That may not happen here (if 3 is rooted in the
problem) but for 2D arrays in general, it is very valuable.

Undoubtedly, it's more valuable and prettier. :)
 
K

Kojak

Le Wed, 4 Mar 2009 05:23:10 -0800 (PST),
(e-mail address removed) a écrit :
Le Tue, 3 Mar 2009 23:39:04 -0800 (PST),
Francogrex a écrit :
Why this below crashes (when the executable is run)? Is there a
way to avoid it? When I replace n=700-1 by n=100-1 it works but I
really need large values of n how can I deal with it? Thanks
#include <stdio.h>
int main()
{
  int i, j, n= 700-1;
  int size=(n*(n-1));
  double tabP [size] [3];

memory allocated for tabP (which isn't a pointeer as the name might
indicate)

No! Memory should be allocated but OP system can't, then apps
crash while trying to initialize tabP. If he try this:

#include <stdio.h>

int main (void)
{
int n = 700 - 1;
int size = (n * (n - 1));
double tabP[size][3];

return printf("Bozo\n");
}

This should also crashed on his system. Unless he can modify
his user stack. But on windows systems I don't know how to do
it or even if it can be done, and I don't give a damn...
Anyway, it's not a good idea too rely apps on user or system
stack limits.

I beg to differ

It's your right. :)
 
K

Keith Thompson

Kojak said:
Le Tue, 3 Mar 2009 23:39:04 -0800 (PST),
Francogrex a écrit :
Why this below crashes (when the executable is run)? Is there a way to
avoid it? When I replace n=700-1 by n=100-1 it works but I really need
large values of n how can I deal with it? Thanks

#include <stdio.h>
int main()
{
int i, j, n= 700-1;
int size=(n*(n-1));
double tabP [size] [3];
for(j=0;j< 3;j++)
{
for (i=0;i<size;i++)
{
tabP [j]=0.0;
printf("%f",tabP [j]);
}
}


No memory reserved for tabP!

[...]

What do you mean "No memory reserved"? tabP is an array object, not a
pointer. It happnes to be a variable-length array (VLA). The program
will *attempt* to allocate 2097 * sizeof(double) bytes for the array
object; if it fails to do so, the behavior is undefined.

One problem with VLAs is that the language doesn't define a mechanism
for reporting allocation failures. Allocating using malloc() and
checking the result will address that; apart from reporting failure,
it's likely that the system make more space available for allocated
objects than for automatic objects.
 
K

Keith Thompson

Keith Thompson said:
Kojak said:
Le Tue, 3 Mar 2009 23:39:04 -0800 (PST),
Francogrex a écrit : [...]
int i, j, n= 700-1;
int size=(n*(n-1));
double tabP [size] [3];
[...]

No memory reserved for tabP!
[...]

What do you mean "No memory reserved"? tabP is an array object, not a
pointer. It happnes to be a variable-length array (VLA). The program
will *attempt* to allocate 2097 * sizeof(double) bytes for the array
object; if it fails to do so, the behavior is undefined.

Whoops, I meant 1463706 * sizeof(double) bytes.

[...]

Kojak, the problem with saying "No memory reserved" is that it usually
refers to declared a pointer object and forgetting to call malloc(),
such as:

char *ptr;
/* No memory reserved for ptr */
strcpy(ptr, "Hello");

The real problem is almost certainly that the memory allocation for
tabP failed; "No memory reserved" generally implies that the memory
allocation wasn't even attempted.
 
K

Kojak

Le Wed, 04 Mar 2009 08:50:31 -0800,
Keith Thompson a écrit :
[...]

Kojak, the problem with saying "No memory reserved" is that it usually
refers to declared a pointer object and forgetting to call malloc(),
such as:

char *ptr;
/* No memory reserved for ptr */
strcpy(ptr, "Hello");

The real problem is almost certainly that the memory allocation for
tabP failed; "No memory reserved" generally implies that the memory
allocation wasn't even attempted.

Well, it seems we are talking differently about the same things. :-D

As I'm not English fluent, my vocabulary isn't as wide as most of
you. I try as far as I can to be as accurate as possible, but it's
not often easy.

Sorry for my weak vocabulary and bad English.

Sincerely,
 
S

Stephen Sprunk

Francogrex said:
Why this below crashes (when the executable is run)? Is there a way to
avoid it? When I replace n=700-1 by n=100-1 it works but I really need
large values of n how can I deal with it? Thanks
...
int i, j, n= 700-1;
int size=(n*(n-1));
double tabP [size] [3];

So, your problem boils down to being able to create an auto array of
29106 doubles but not an auto array of 1463706 doubles (assuming int can
even _hold_ the number 1463706, which isn't guaranteed -- long would be
safer). This isn't surprising.

Many implementations have a limit on how much space auto variables can
consume in each function; this limit is high enough that it usually
doesn't matter, but when you push things, you eventually hit it -- as is
almost certainly happening in this case.

I suggest you avoid creating more than 32kB of auto variables in a
single function; if you need more space than that, get it from malloc()
et al. There are limits to how much memory you can obtain that way as
well, but they're typically much, much higher than for auto variables,
and at least you'll know if it fails instead of getting a mysterious
crash...

S
 
F

Francogrex

So, your problem boils down to being able to create an auto array of
29106 doubles but not an auto array of 1463706 doubles (assuming int can
even _hold_ the number 1463706, which isn't guaranteed -- long would be
safer).  This isn't surprising.

Many implementations have a limit on how much space auto variables can
consume in each function; this limit is high enough that it usually
doesn't matter, but when you push things, you eventually hit it -- as is
almost certainly happening in this case.

I suggest you avoid creating more than 32kB of auto variables in a
single function; if you need more space than that, get it from malloc()
et al.  There are limits to how much memory you can obtain that way as
well, but they're typically much, much higher than for auto variables,
and at least you'll know if it fails instead of getting a mysterious
crash...

ok thanks to everyone for the help. I realize that I have to use malloc
( ) [and possibly free( ) as well in conjunction if multiple calls
needed]. Now it works quite well.
 
C

CBFalconer

Francogrex said:
Why this below crashes (when the executable is run)? Is there a
way to avoid it? When I replace n=700-1 by n=100-1 it works but
I really need large values of n how can I deal with it? Thanks

#include <stdio.h>
int main()
{
int i, j, n= 700-1;
int size=(n*(n-1));

To start, size may not be big enough. An int must hold at numbers
at least as large as 32767. When you need larger numbers, try
long.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,144
Messages
2,570,823
Members
47,369
Latest member
FTMZ

Latest Threads

Top