How to Determine the Amount of Linux System Ram in C++

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



Leave a reply



Submit