I'm trying to read matrix of integers from file using mmap. If I receive it as char pointer from mmap function, I see everything correct but if I use int pointer, it gives me stale data. Problem with using char pointer is that I need to parse whole string using strtok or something else and get integers one by one. My matrix size is going to be 4k * 4k hence making that many calls to sscanf and strtok is not efficient. Please look at the program and output
#define INTS 3 * 3
int main()
{
FILE* in = fopen("int_file", "rb");
int* ints = (int*)mmap(0, INTS * sizeof(int),
PROT_READ, MAP_FILE | MAP_PRIVATE, fileno(in),0);
fclose(in);
for(int i = 0; i < INTS; ++i) {
std::cout << ints[i] << std::endl;
}
munmap(ints, INTS * sizeof(int));
return 0;
}
Contents of int_file is
510 20 30
40 50 60
100 200 10000
Output
540029237
857747506
808716848
540030240
822751286
84097028
The ACSII value of the text is getting printed.
Your text seems like:
510 20 30...
From ASCII table (to explain what I want to tell):
No. ASCII (hex)
Space -> 20
0 -> 30
1 -> 31
2 -> 32
3 -> 33
5 -> 35
int
is 4
byte in size, so, taking first 4
bytes:
Converting to ASCII, "510 "
gives "35 31 30 20"
in memory which is 0x20303135
(540029237
as decimal) for a little endian machine.
Similarly, next 4
bytes "20 3"
gives 0x33203032
(857747506
as decimal).
This is what you are getting.
You need to convert each ACSII to integer using atoi() or similar, in this case.
But you may store your integers as their binary value itself rather than keeping it as ASCII. The file will not be human readable but it will do your purpose.
Reading it as int *
is possible if the data in file is stored from int array or continuous memory through calloc. Writer should look like,
#include <iostream>
#include <sys/mman.h>
#include <stdio.h>
using namespace std;
int inst[] = {510, 20, 30, 40, 50, 60, 100, 200, 10000 };
#define INTS 3 * 3
int main()
{
FILE* out = fopen("int_file", "wb"); // Error checks are needed
char *ptr = (char *) inst;
fwrite( ptr, sizeof( int ), INTS, out );
fclose( out);
return 0;
}
Then the reader can read using mmap
like as it is in your code,
#include <iostream>
#include <sys/mman.h>
#include <stdio.h>
using namespace std;
#define INTS 3 * 3
int main()
{
FILE* in = fopen("int_file", "rb"); // Error checks are needed
int* ints = (int*)mmap(0, INTS * sizeof(int),
PROT_READ, MAP_FILE | MAP_PRIVATE, fileno(in),0);
fclose(in);
for(int i = 0; i < INTS; ++i) {
std::cout << ints[i] << std::endl;
}
munmap(ints, INTS * sizeof(int));
return 0;
}
If not stored from array or continuous memory, then using char *
and strtok
and atoi
is the best solution..