Having this:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define GB (1<<30)
#define N 10000L //number of virtual blocks(arrays)
int main (void) {
int *ar[N];
for(int i =0; i<N ; i++)
{
ar[i]=malloc(GB); //alloc virtually one GB
if(!ar[i]){
printf("done at %in",i);
return 0;
}
}
printf("allocated %li blocksn",N);
for(int i =0; i<N ; i++)
{
memset(ar[i],2,GB); // get physical gigs for that array
printf("wrote to %i GBn",i+1);
}
return 0;
}
But I will not get even one:
allocated 10000 blocks //virtual memory (one block==1GB)
wrote to 1 GB //real memory (not really
Command terminated
Press ENTER or type command to continue
I know I have at leaset 4 gigs on my machine and I also know OS has some limit it needs to operate, however I cannot get even 2 GB for user space? That is strange. Can someone explain please?
$uname -a
:
`4.19.0-9-amd64 #1 SMP Debian 4.19.118-2 (2020-04-29) x86_64 GNU/Linux
EDIT:
It gets stranger:
Now if I run (after an hour from the previous output):
allocated 10000 blocks
wrote to 1 GB
wrote to 2 GB
Command terminated
Press ENTER or type command to continue
so it gets through 2 time in for loop, and allocates 2GB of real memory, but before an hour, I catch only 1GB and something (not full 2GB).
addition info:
$free -h
:
total used free shared buff/cache available
Mem: 3.7Gi 1.1Gi 2.2Gi 236Mi 404Mi 2.2Gi
Swap: 0B 0B 0B
How can I take advantage from these information? So it is I said -> I have 4GB (total
), but can get 2GB. That is maximum for user space?
2
Answers
Note: This answer does not solve the problem OP was having because it’s based on fake code originally in the question, and still present in the question after the first request to correct fake code was made and acted upon. It does explain the question as originally asked.
If the code you posted is accurate now, your problem is that you are attempting to call functions without valid declarations for them (I see no
#include
directives). This is invalid C and the compiler should warn (or ideally error out) if you do it. Always add-Werror=implicit-function-declaration
to get it to do that.The particular mechanism of your crash is likely this:
memset
takes asize_t
(unsigned long
) as its third argument, but without a prototype, the function is being called as if the type of the function matched the argument types you provided (subject to default promotions). This produces undefined behavior.1<<30
has typeint
, notunsigned long
, and on x86_64 ABI,int
is passed in the low 32 bits of a 64-bit register, with arbitrary junk allowed in the upper bits. So rather than passing 1 GB tomemset
, you’re passing some astronomically large number.Possibly a memory or swap limitation.
On a 4GB Ubuntu 18 VM, I get:
syslog says: