Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are large char buffers OK to use in C

Tags:

c

I need to store a 'large' file (say a little under 2mb) in memory and I want to know if it's OK to just use

char buffer[2048000];

Is there a better way to handle it? Any performance issues with using large char arrays?

like image 644
user740521 Avatar asked Feb 19 '16 11:02

user740521


4 Answers

Yes there could be issues, most C implementations will allocate that buffer on the stack if it's a variable of automatic storage duration, and the amount of "stack memory" available for use can be surprisingly small.

Your best bet is to use malloc for anything larger than a few kilobytes. Just remember to call free at an appropriate point.

Making it static is another possibility or making it global might help.

like image 84
Bathsheba Avatar answered Oct 20 '22 09:10

Bathsheba


If you declare it in the global namespace, no problems. It's just a block of memory, so no performance issues whatsoever.

Within a function, the variable is going to be allocated on the stack, and you can easily run out of stack space. Avoid this approach. If you need it only in a local scope, allocate memory with malloc or use mmap to handle the file.

like image 31
Karoly Horvath Avatar answered Oct 20 '22 10:10

Karoly Horvath


You can allocate a buffer in 3 ways:

1) On the stack. This happens when you define a non-static array within function scope. The stack size depends on your compiler and architecture, but the rule of thumb that one should not try and allocate big buffers there.

2) On the heap (using malloc). You can safely allocate big buffers there.

3) In the program data segment. This happens when you define a static array in any scope. It's ok to allocate big arrays there as well.

like image 20
Igor R. Avatar answered Oct 20 '22 10:10

Igor R.


When you statically allocate the buffer in this way, you're asking the computer for 2048000 contiguous bytes free in memory. That isn't the same as asking for 2048000 bytes of free memory, since it must also be contiguous. You can therefore imagine that the larger the space to allocate is, the less likely you will find that amount of contiguous memory free.

The common approach is to use malloc to allocate the memory. This gives the program a chance to check the return value and act on it in the case in which NULL is returned (no memory given). This doesn't reduce the possibility of a memory problem from happening, but it also allows you, the programmer, to have more control in such a case.

In cases in which you need to allocate large amounts of memory (large enough that this could be an issue), one approach is to create a linked list of smaller char arrays. When you reach the end of one array, you follow the linked list to the next array and continue reading. This is best accompanied with a couple helper methods so the caller doesn't have to worry about these details.

This ensures that you don't need 2MB of contiguous memory but 10 contiguous arrays at 200 kb each, meaning they could potentially be in separate positions in memory.

In applications that pre-allocate memory used in the program (as in the case of games), the common approach is this, with multiple smaller allocated arrays in a linked list. The buffer is also written to initially since the operating system has been known to allocate memory lazily and not actually allocate the memory until it is accessed for the first time, which as you can imagine can create problems when the memory is actually required by the program. The big advantage in pre-allocating memory is that no new memory is usually required during the life of the program, and the entire linked list can be freed at the end without having to keep track of individual pointer allocations.

like image 28
Neil Avatar answered Oct 20 '22 10:10

Neil