2

My question is pretty straightforward.

I'm building a small program to analyse and simulate random text using Markov chains. My first MC had memory of size 2, working on the alphabet {a, b, ..., z}. Therefore, my transition matrix was of size 26 * 26 * 26.

But now, I'd like to enhance my simulation using a MC with memory of size 4. Therefore, I need to store my probabilities of transitions in a 5D array of size 26*26*26*26*26.

The problem is (I believe), that C doesn't allow me to declare and manipulate such a array, as it might be too big. In fact, I got a segmentation faults 11 prompt when writing :

int count[26][26][26][26][26]

Is there a way to get around this restriction?

Thanks!

lurker
  • 56,987
  • 9
  • 69
  • 103
Hermès
  • 215
  • 2
  • 7
  • 5
    Allocate your array on the heap, rather than on the stack. – hnefatl Feb 04 '18 at 14:43
  • 2
    I think that for this case (a small, standalone program) declaring it as a static or global variable actually is the cleanest option - the current answers under-emphasize this. – kfx Feb 04 '18 at 18:39
  • that is ~47million entries! That will exceed the available size of the stack (especially on windows) Suggest moving that array declaration to 'file global space'. I.E. outside of any function definition. – user3629249 Feb 05 '18 at 06:59

4 Answers4

5

On a typical PC architecture with 32-bit integers, int count[26][26][26][26][26] creates an object of size 47525504 bytes, 47MB, which is manageable on most current computers, but is likely too large for automatic allocation (aka on the stack).

You can declare count as a global or a static variable, or you can allocate it from the heap and make count a pointer with this declaration:

int (*count)[26][26][26][26] = calloc(sizeof(*count), 26);
if (count == NULL) {
    /* handle allocation failure gracefully */
    fprintf(stderr, "cannot allocate memory for 5D array\n");
    exit(1);
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • 1
    Also, make sure to check `count` for null after the call to `calloc`, since the allocation may fail, especially if you go to the next dimension. – bruceg Feb 04 '18 at 17:14
4

Make it global1 or make it static or dynamically allocate the same amount of memory. Dynamic memory allocation allocates memory from a portion of memory which doesn't have the constraint to an extent larger than the one you faced. Variables having automatic storage duration are likely to stored in stack in most implementations. Dynamic memory belongs to heap in most implementations.

You can do this (Illustration):-

int (*a)[26][26][26][26] = malloc(sizeof *a *26);
if(!a){ perror("malloc");exit(1);}
...
free(a);

1static storage duration - all variables defined in file scope have static storage duration.

lurker
  • 56,987
  • 9
  • 69
  • 103
user2736738
  • 30,591
  • 5
  • 42
  • 56
  • Note my answer may sounds a bit different...because standard doen't mention heap or stack - it is part of language implementation... That's why those bold text in answer.... – user2736738 Feb 04 '18 at 15:19
2

With this kind of array declaration, your data will be stored in stack. And stack have usually only 8 MB on Unix like systems and 1 MB on Windows. But you need at least 4*26^5 B (roughly 46 MB).

Prefered solution would be allocate this array on heap using malloc.

But you can also instruct compiler to increase the stack size...

Recoder
  • 818
  • 8
  • 10
Matěj Pokorný
  • 16,977
  • 5
  • 39
  • 48
-3

Try this

#define max=11881376   //answer of 26*26*26*26*26
int count[max];   //array
Bo Persson
  • 90,663
  • 31
  • 146
  • 203
Kavya
  • 1