How do you determine the amount of Linux system RAM in C++?
On Linux, you can use the function sysinfo
which sets values in the following struct:
#include <sys/sysinfo.h>
int sysinfo(struct sysinfo *info);
struct sysinfo {
long uptime; /* Seconds since boot */
unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
unsigned long totalram; /* Total usable main memory size */
unsigned long freeram; /* Available memory size */
unsigned long sharedram; /* Amount of shared memory */
unsigned long bufferram; /* Memory used by buffers */
unsigned long totalswap; /* Total swap space size */
unsigned long freeswap; /* swap space still available */
unsigned short procs; /* Number of current processes */
unsigned long totalhigh; /* Total high memory size */
unsigned long freehigh; /* Available high memory size */
unsigned int mem_unit; /* Memory unit size in bytes */
char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding for libc5 */
};
If you want to do it solely using functions of C++ (I would stick to sysinfo
), I recommend taking a C++ approach using std::ifstream
and std::string
:
unsigned long get_mem_total() {
std::string token;
std::ifstream file("/proc/meminfo");
while(file >> token) {
if(token == "MemTotal:") {
unsigned long mem;
if(file >> mem) {
return mem;
} else {
return 0;
}
}
// Ignore the rest of the line
file.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
return 0; // Nothing found
}
Getting RAM size in C, linux, non-precise result
What you're seeing is caused by floating point inaccuracy. You must be careful when going between floating points and integers and when printing floating points.
Since floating points cannot represent all numbers exactly, it often attempts to get as close as possible. What is likely happening is that instead of 16, totalMemory
is something like 15.999999999987
and then when this gets converted to an int, it gets truncated to 15.
There are two ways you can fix this: if you know totalMemory
is divisible by 1024*1024
, then just use integers (this would not work in the case of non integer gigabytes). Since you're using an integer anyway, you might as well use this approach. (768MB cannot be expressed as an integral amount of GB).
The other option is to add in an epsilon to prevent this. In other words, instead of using totalMemory
, you would use something like totalMemory + 1e-7
. The epsilon is too insignificant to make a meaningful difference, but it can push something like 15.999...
up to 16
.
By the way, floating point problems are only part of your problem. If you're going to use an integer, you probably want to use MB instead of GB. How can an integer represent something like 4.5GB (although that's very rare these days)?
How to determine memory size via C code
Use free
$ free
total used free shared buff/cache available
Mem: 8093896 3657260 2163392 68360 2273244 4109636
Swap: 27733868 1045556 26688312
In a program:
/* mem.c */
int main()
{
system("free");
}
And as a proof of concept:
$ gcc mem.c
$ ./a.out
total used free shared buff/cache available
Mem: 8093896 3692808 2122384 68360 2278704 4074036
Swap: 27733868 1045544 26688324
How to get available memory C++/g++?
Having read through these answers I'm astonished that so many take the stance that OP's computer memory belongs to others. It's his computer and his memory to do with as he sees fit, even if it breaks other systems taking a claim it. It's an interesting question. On a more primitive system I had memavail()
which would tell me this. Why shouldn't the OP take as much memory as he wants without upsetting other systems?
Here's a solution that allocates less than half the memory available, just to be kind. Output was:
Required FFFFFFFF
Required 7FFFFFFF
Required 3FFFFFFF
Memory size allocated = 1FFFFFFF
#include <stdio.h>
#include <stdlib.h>
#define MINREQ 0xFFF // arbitrary minimum
int main(void)
{
unsigned int required = (unsigned int)-1; // adapt to native uint
char *mem = NULL;
while (mem == NULL) {
printf ("Required %X\n", required);
mem = malloc (required);
if ((required >>= 1) < MINREQ) {
if (mem) free (mem);
printf ("Cannot allocate enough memory\n");
return (1);
}
}
free (mem);
mem = malloc (required);
if (mem == NULL) {
printf ("Cannot enough allocate memory\n");
return (1);
}
printf ("Memory size allocated = %X\n", required);
free (mem);
return 0;
}
Finding amount of RAM using C++
With Linux and GCC, you can use the sysconf
function included using the <unistd.h>
header.
There are various arguments you can pass to get hardware information. For example, to get the amount of physical RAM in your machine you would need to do:
sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE);
See the man page for all possible usages.
You can get the maximum stack size of a process using the getrlimit
system call along with the RLIMIT_STACK argument, included using the <sys/resource.h>
header.
To find out how many processes are running on the current machine you can check the /proc
directory. Each running process is represented as a file in this directory named by its process ID number.
Memory usage of current process in C
You can always just open the 'files' in the /proc
system as you would a regular file (using the 'self' symlink so you don't have to look up your own pid):
FILE* status = fopen( "/proc/self/status", "r" );
Of course, you now have to parse the file to pick out the information you need.
Related Topics
Restrict Variadic Template Arguments
Changing Dpi Scaling Size of Display Make Qt Application's Font Size Get Rendered Bigger
Clang: No Out-Of-Line Virtual Method Definitions (Pure Abstract C++ Class)
How to Get File Extension from String in C++
Can Lambda Functions Be Recursive
How to Parallelize a for Loop Through a C++ Std::List Using Openmp
How to Resize a 2D Vector of Objects Given the Width and Height
Std::Forward_List and Std::Forward_List::Push_Back
How to Add Static Libraries to a Visual Studio Project
How to Break Shared_Ptr Cyclic Reference Using Weak_Ptr
Passing a Pointer to a Class Member Function as a Parameter
Attribute & Reflection Libraries for C++
Mock Non-Virtual Method C++ (Gmock)
Openmp: What Is the Benefit of Nesting Parallelizations
Creating a Thread Pool Using Boost
Lambda Capture and Parameter with Same Name - Who Shadows the Other? (Clang VS Gcc)