Using mmap () instead of malloc ()

I am trying to do an exercise that is done with system calls, and you need to allocate memory for struct *. My code is:

myStruct * entry = (myStruct *)mmap(0, SIZEOF(myStruct), PROT_READ|PROT_WRITE, MAP_ANONYMOUS, -1, 0); 

To clarify, I cannot use malloc() , but I can use mmap() . I had no problems with this on Windows in Netbeans, now, although I compile and run from the command line in Ubuntu, I get a “Segmentation Error” every time I try to access it.

Is there a reason why it will work on one and not on the other, and is mmap() valid way to allocate memory this way? My concern was that I was going to allocate large chunks of memory for each mmap() call initially, now I just can't get it to work.

Also, the error returned by my mmap is 22 - Invalid Argument (I did some troubleshooting when writing the question to check for the error in the above code). The address is 0, the custom function SIZEOF() works in other mmap arguments, I use MAP_ANONYMOUS , so the fd and offset parameters should be -1 and 0, respectively.

Is there something wrong with the PROT_READ|PROT_WRITE ?

+6
source share
2 answers

You need to specify MAP_PRIVATE in your flags.

 myStruct * entry = (myStruct *)mmap(0, SIZEOF(myStruct), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 

From the man page :

The flags argument determines whether the updates to display are visible to other processes that display the same region, and the updates are transferred to the main file. This behavior is determined , including exactly one of the following values ​​in the flags:

You only need one of the MAP_PRIVATE or MAP_SHARED flags - but you did not give any of them.

Full example:

 #include <sys/mman.h> #include <stdio.h> typedef struct { int a; int b; } myStruct; int main() { myStruct * entry = (myStruct *)mmap(0, sizeof(myStruct), PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (entry == MAP_FAILED) { printf("Map failed.\n"); } else { entry->a = 4; printf("Success: entry=%p, entry->a = %d\n", entry, entry->a); } return 0; } 

(The above, without MAP_PRIVATE , of course, is a good example of what you could provide as MCVE . This makes it much easier for others to help you, because they can see exactly what you have done and test their proposed solutions. You should always provide MCVE).

+6
source

The manual page for mmap() indicates that you must specify exactly one of MAP_SHARED and MAP_PRIVATE in the flags argument. In your case, to act like malloc() , you need MAP_PRIVATE :

 myStruct *entry = mmap(0, sizeof *entry, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 

(I also made this more idiomatic C by omitting the harmful conversion and matching sizeof with the actual variable, not its type).

+3
source

Source: https://habr.com/ru/post/1011466/


All Articles