ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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.
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?
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.
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.
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++.
Distribution: Solaris 11.4, Oracle Linux, Mint, Debian/WSL
Posts: 9,789
Rep:
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.
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;
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.
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; )
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;
}
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.