LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 01-26-2005, 12:49 PM   #1
bigfatdud
LQ Newbie
 
Registered: Oct 2004
Posts: 5

Rep: Reputation: 0
c++: array size limit?


Hello:

I'm just trying to make a 2 dimensional integer array with the following code but keep getting a segmentation fault... I'm running on mandrake 10.1 and gcc 3.4.1.

=============================
#include <iostream.h>

int main()
{
int i[2000][2000];
int j,k;

for (j=0; j<2000; j++) {
for (k=0; k<2000; k++) {
i[j][k] = j+k;
}
}

return 0;
}
=============================

Works okay with smaller arrays (e.g. 1000x1000)... So is there a size limit on the size of arrays? If so, how can I change it? If not, any suggestions on how I should approach?

Thank you very much...

dud
 
Old 01-26-2005, 12:58 PM   #2
Matir
LQ Guru
 
Registered: Nov 2004
Location: San Jose, CA
Distribution: Debian, Arch
Posts: 8,507

Rep: Reputation: 128Reputation: 128
My guess is that the maximum size of an array is 4.2 billion (2^32) bytes, as an array position (for 1-d array) is calculated in the processor by:

Code:
base+index*size
where base is the base address of the array, index is the array index, and size is the size of a single element. for a two dimensional array, it is probably:
Code:
base+rowindex*colsize+colindex*size
So, for this all to fit in 32 bits, the maximum size of a two dimensional array must be:
Code:
numrows*numcols*sizeof(element)<(2^32)
Edit:
Your 2000x2000 is only hitting 16,000,000 (2000*2000*4 bytes). The only other thing I can imagine is some sort of limitation I am not thinking of... such as declaring it statically.

Last edited by Matir; 01-26-2005 at 12:59 PM.
 
Old 01-26-2005, 12:59 PM   #3
orgcandman
Member
 
Registered: May 2002
Location: new hampshire
Distribution: Fedora, RHEL
Posts: 600

Rep: Reputation: 110Reputation: 110
first off, I'd use a dynamically allocated array. The static array will make your binary bloated like crazy (if an int is defined as 32 bits, you have 128000000 bits allocated by the compiler, meaning 16,000,000 bytes. That's a BIG binary for such small code)

int **i = new int[2000][2000];

or something like that ( I'm somewhat hazy on how to do a multi-dimensional array in C++)

Also, I think that you're trying to addres a memory region that's way to large (think of 2000 * 2000, you get 4000000 byte address. This is more than most systems can address if my math is correct, which it probably isn't as I'm doing this back-of-the-envelope.)

Therefore, yes there's a limitation, but it's hardware related not software related.

-Aaron
 
Old 01-26-2005, 02:13 PM   #4
Hivemind
Member
 
Registered: Sep 2004
Posts: 273

Rep: Reputation: 30
The size of an array does nothing to the size of the executable. However, an array that large is simply too big to be allocated on the stack on most systems. Allocate it dynamically or, probably better, use a container from the C++ standard library that handles the dynamic allocation for you. A std::vector for example.
And btw, don't include iostream.h, include iostream. iostream.h is not part of standard C++.
 
Old 01-26-2005, 02:22 PM   #5
jlliagre
Moderator
 
Registered: Feb 2004
Location: Outside Paris
Distribution: Solaris 11.4, Oracle Linux, Mint, Debian/WSL
Posts: 9,789

Rep: Reputation: 492Reputation: 492Reputation: 492Reputation: 492Reputation: 492
Put your array in the static area by prefixing it with the static keyword:
Code:
static int i[2000][2000];
Without doing it, it goes to the heap, which is limited in size by the linker (can be something like 1 megabyte) and is not suitable for storing large variables.

Be aware that your function is no more reentrant after that.
 
Old 01-26-2005, 02:26 PM   #6
Matir
LQ Guru
 
Registered: Nov 2004
Location: San Jose, CA
Distribution: Debian, Arch
Posts: 8,507

Rep: Reputation: 128Reputation: 128
Best of all, do:

Code:
int **array=malloc(2000*2000*sizeof(int));
or something similar. or use the fancy "new" keyword in C++.

(for those who say malloc is not C++ enough, that may be true, but it's still functional)
 
Old 01-26-2005, 02:43 PM   #7
Hivemind
Member
 
Registered: Sep 2004
Posts: 273

Rep: Reputation: 30
Don't use malloc()/free() in C++, it doesn't know about constructors and destructors. For more details, read Meyers.
 
Old 01-26-2005, 03:20 PM   #8
Matir
LQ Guru
 
Registered: Nov 2004
Location: San Jose, CA
Distribution: Debian, Arch
Posts: 8,507

Rep: Reputation: 128Reputation: 128
malloc/free is fine if you're not doing it to objects. and what is Meyers?
 
Old 01-26-2005, 04:50 PM   #9
Hivemind
Member
 
Registered: Sep 2004
Posts: 273

Rep: Reputation: 30
malloc and free is fine in C, in C++ use new and delete.
Scott Meyers has written very goo C++ books, the "Effective C++"-series.
 
Old 01-26-2005, 05:07 PM   #10
bigfatdud
LQ Newbie
 
Registered: Oct 2004
Posts: 5

Original Poster
Rep: Reputation: 0
Thanks a bunch for all the help.

Cheers to all.
Dud
 
Old 01-26-2005, 05:39 PM   #11
thadeu
LQ Newbie
 
Registered: Jul 2003
Location: Rio de Janeiro
Distribution: SuSE 9.2
Posts: 3

Rep: Reputation: 0
I learn recently an way to create/destroy dynamic array using new/delete, as example:

// creating an int NxN array
int N = 1000;
int **p;
p = new int*[N];
for( int i = 0; i < N; i++ )
{
p[i] = new int[N];
for( int j = 0; j < N; j++ )
p[i][j] = 0;
}

...

// destoying the array
for( int i = 0; i < N; i++ )
delete [] p[i];
delete [] p;
 
Old 01-26-2005, 08:11 PM   #12
Matir
LQ Guru
 
Registered: Nov 2004
Location: San Jose, CA
Distribution: Debian, Arch
Posts: 8,507

Rep: Reputation: 128Reputation: 128
Does:

Code:
int **array=new int[1000][1000];
work as expected?
 
Old 01-27-2005, 03:57 AM   #13
kees-jan
Member
 
Registered: Sep 2004
Distribution: Debian, Ubuntu, BeatrIX, OpenWRT
Posts: 273

Rep: Reputation: 30
Short answer: Probably no (depends on what you expect, though).

the problem is that with this code, array[x][y] cannot be properly computed, because int** has insufficient information about array sizes.

What happens under water is that to find the proper memory address of array[x][y], the compiler computes something like
Code:
x*sizeof(array[0]) + y*sizeof(array[0][0])
In order to work as expected, sizeof(array[0]) should equal 1000*sizeof(int), which is 4000. However, since array is of type int**, sizeof(array[0]) equals sizeof (int*), which is 4. Hence the wrong array element will be accessed.

Groetjes,

Kees-Jan
 
Old 01-27-2005, 08:09 AM   #14
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32
Not only that, you will also get a compiler error.

error: cannot convert `int (*)[1000]' to `int**' in initialization

To create a multidimensional array dynamically, you have to first initialize the pointer array, then initialize memory for each pointer in that array. This isn't quite the same as a static multidemensional array because it is not likely to be a contiguous block of memory.

Another option is to just initialize a contiguous block of memory for a single dimension array and index it appropriately. (e.g. index = x + y*width; )

Last edited by deiussum; 01-27-2005 at 08:18 AM.
 
Old 01-27-2005, 11:19 AM   #15
jim mcnamara
Member
 
Registered: May 2002
Posts: 964

Rep: Reputation: 36
There are probably stack size limits enforced. SIGSEGV is sent when those limits are turned on and you blow past them. You can check to see with something like this:
Code:
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

/* macro - check return codes for (-1) */
#define ckEOF(z)\
if( (z)==EOF)\
{ \
    perror("Fatal error"); \
    exit(EXIT_FAILURE); \
}
void print_limit(rlim_t  value)
{
    if(value==RLIM_INFINITY)
    {
    	fprintf(stdout,"%s\n","Infinite");
    }
    else
    {
    	fprintf(stdout,"%u\n",value);
    }
}

/* show the current hard & soft limits, current usage for a resource */
void showlimit(int resource)
{
    struct rlimit lim;
    struct rusage r_usage;
    long usage=0;
    char what_limit[32]={0x0};
    char tmp[24]={0x0};
    
    ckEOF(getrlimit(resource, &lim));
    ckEOF(getrusage(RUSAGE_SELF, &r_usage));

    switch(resource)
    {
      case RLIMIT_STACK:
           strcpy(what_limit,"Stack size -");
           usage+=r_usage.ru_isrss;               /* integral unshared stack " */
           break;
      case RLIMIT_AS:
           usage+=r_usage.ru_ixrss;               /* integral shared memory size */
           usage+=r_usage.ru_idrss;               /* integral unshared data " */
           usage+=r_usage.ru_isrss;               /* integral unshared stack " */      
           strcpy(what_limit,"All memory segments -");
           break;
      case RLIMIT_DATA:   
           usage+=r_usage.ru_idrss;               /* integral unshared data " */   
           strcpy(what_limit,"Data segment size -"); 
           break;
      default:
           break;
    
    }   	
    fprintf(stdout,"%22s hard limit    ",what_limit);
    print_limit(lim.rlim_max);
    fprintf(stdout,"%22s soft limit    ",what_limit);
    print_limit(lim.rlim_cur);
    if(usage==0)
    {
        strcpy(tmp,"not implemented");
    }
    else
    {
      	sprintf(tmp,"%-12d",usage);
    }       

    fprintf(stdout,"%22s Current usage %s\n"," ", tmp);    
}
       
int main(int argc, char *argv[])
{
    showlimit(RLIMIT_STACK);
    showlimit(RLIMIT_DATA);
    showlimit(RLIMIT_AS);
    return 0;
}
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Is there a default size limit to a dictionary, list or array declaration ? Linh Programming 2 06-08-2004 11:35 AM
Size of an array in C Hady Programming 6 04-06-2004 05:33 AM
PERL: Size of an array of an Array inspleak Programming 2 03-10-2004 02:24 PM
size of an array Longinus Programming 8 03-08-2004 01:48 PM
getting size of an array in c++ qanopus Programming 8 11-06-2003 05:19 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:04 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration