问题
This is from the book: Understanding and Using C Pointers
If memory is re‐ peatedly allocated and then lost, then the program may terminate when more memory is needed but malloc cannot allocate it because it ran out of memory. In extreme cases, the operating system may crash. This is illustrated in the following simple example:
char *chunk;
while (1) {
chunk = (char*) malloc(1000000);
printf("Allocating\n");
}
The variable chunk is assigned memory from the heap. However, this memory is not freed before another block of memory is assigned to it. Eventually, the application will run out of memory and terminate abnormally.
So to my question: I have this sample code:
int main(int argc, char *argv[]){
char *chunk;
while (1) {
chunk = (char*) malloc(100000000);
printf("Allocating\n");
}
}
Well I am expecting my system to run out of memory but the program keeps running and I see the text
Allocating...
all the time?
回答1:
On Linux I presume?
Just because you get back a pointer doesn't mean you actually reserved that memory. You have to physically touch the page for it to be yours.
回答2:
When there isn't enough memory malloc probably returns NULL. Add a check for that.
while (1) {
printf("Allocating\n");
chunk = malloc(100000000);
if ( chunk == NULL )
{
printf("Memory allocation not successful.\n");
}
else
{
printf("Memory allocation successful.\n");
}
}
回答3:
The program you run is not incorrect. It doesn't have to terminate abnormally. The reason of premature termination is that it consumes all memory in your computer, so if you don't take the correct measures, it will die.
Linux (and unix in general) imposes some limits to the processes running on a system. In linux, all these limits (see ulimit(2) system call) are by default, fixed to unlimited.
When a process in linux tries to get more memory than the system has and allocates the remainder virtual memory, the kernel selects a process (the best candidate is the process trying to eat all memory) and kills it to recover some memory. This is perhaps why the text you read says it terminates abnormally. You note this because the system passes a while trying to swap in all the memory you are allocating and the swapper demands all the kernel attention (so your system seems to hang for a while ---it doesn't, just wait)
But you can do this kind of test: Try to limit the virtual memory allocated to a process (with ulimit command, see bash(1)), so the system can cope with memory eating programs. Use the command
$ ulimit -v 100000 # this allows for 100.000 kb of virtual memory
and rerun the program (It will be able to expand up to 100Mb and no more). You'll see it doesn't stop. It runs forever. Once it has exhausted all the memory it can, malloc(3) begins to return NULL and the process never stop. You'll see (via ps(1) command) that the program has allocated up to the limit you imposed and no more and it's running, consuming 100% of cpu time. And everything is under control. I tried the following variant of your program:
#include <stdlib.h>
#include <stdio.h>
char *chunk;
main()
{
int i = 0;
while (malloc(1000000)) i++;
printf("run for %i times.\n", i);
}
which counts the number of successful allocations before it runs out of memory and prints that number on stdout. After fixing ulimit to 100Mb (ulimit -v 1000000) this program output:
$ pru
run for 97 times.
(you will see this is under 100Mb) So, voila!
来源:https://stackoverflow.com/questions/29610445/how-come-this-c-program-does-not-crash