Mapowanie pliku do pamięci

0

Piszę program, przy użyciu funkcji z biblioteki windows.h, który ma za zadanie stworzyć plik, zmapowanie go, a następnie zapisanie do niego tablicy złożonej z wartości typu double. Jedyne, co nie działa poprawnie jest sam zapis do pliku, gdyż zamiast wartości double widoczne są pliku "dziwne" znaki. Liczę na podpowiedzi, co robię nie tak.

 

#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>

using namespace std;

double **createMatrix()
{
	double **matr = (double **)malloc(8*sizeof(double*));
	if (!&matr)
	{
		puts("Can't allocate memory!");
		abort();
	}

	for (int i = 0; i<8;++i)
	{
		matr[i] = (double *)malloc(12*sizeof(double));
	}

	for (int i=0;i<8;++i)
	{
		for(int j=0;j<12;++j)
		{
			matr[i][j]=(i+1)*(j+3);
			printf("%.2lf ",matr[i][j]);
		}
		printf("\n");
	}
	return &matr[0];
}

void freeMatrix(double **a)
{
	for (int i=0;i<8;++i)
	{
		free(a[i]);
	}
	free(a);
}

int main(int argc, char **argv)
{
	HANDLE plik, mappedFile;
	char  *poi;
	LPCWSTR fileName = L"plik.txt";
	double **matrix = createMatrix();

	plik = CreateFile(fileName, GENERIC_READ|GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0);

	if (!plik)
	{
		puts("Can't create file!");
		abort();
	}

	mappedFile = CreateFileMapping(
		plik,
		NULL,
		PAGE_READWRITE,
		0,
		96*sizeof(double),
		NULL);

	poi = (char *)MapViewOfFile(
		mappedFile,
		FILE_MAP_ALL_ACCESS,
		0,
		0,
		0);

	if (!poi)
	{
		puts("Can't allocate Memory!");
		abort();
	}

	memcpy(poi,matrix,96*sizeof(double));

	UnmapViewOfFile((void*)poi);
	CloseHandle(mappedFile);
	CloseHandle(plik);

	freeMatrix(&matrix[0]);
	getchar();
	return 0;
}

0

A co oczekiwałeś że się zapisze? Przecież kopiujesz tam surowe bajty - te dziwne znaczki to reprezentacja liczb zmiennoprzecinkowych zinterpretowana jako znaki. Otwórz hexedytorem i pooglądaj sobie 64 bitowe fragmenty, zapewne będziesz mieć możliwość zinterpretowania ich jako liczby podwójnej precyzji IEE754.

A no i nie zauważyłem, że to w ogóle nie jest ciągły obszar pamięci. @PannaGrant niżej ma rację.

0

Funkcja createMatrix zwraca wskaźnik na tablicę wskaźników. Te double są gdzieś na stercie. To co tworzysz w createMatrix to nie jest to samo co np. double tab[8][12] a tego właśnie oczekujesz pisząc memcpy(poi,matrix,96*sizeof(double));

0

Mój kod teraz prezentuje się tak.

 
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>

using namespace std;

void createMatrix(double tab[8][12])
{
	for (int i=0;i<8;++i)
	{
		for(int j=0;j<12;++j)
		{
			tab[i][j]=(i+1)*(j+3);
			printf("%.2lf ",tab[i][j]);
		}
		printf("\n");
	}

}


int main(int argc, char **argv)
{
	HANDLE plik, mappedFile;
	char  *poi;
	LPCWSTR fileName = L"plik.txt";
	double tab[8][12];
	createMatrix(tab);
	
	plik = CreateFile(fileName, GENERIC_READ|GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0);

	if (!plik)
	{
		puts("Can't create file!");
		abort();
	}

	mappedFile = CreateFileMapping(
		plik,
		NULL,
		PAGE_READWRITE,
		0,
		96*sizeof(double),
		NULL);

	poi = (char *)MapViewOfFile(
		mappedFile,
		FILE_MAP_ALL_ACCESS,
		0,
		0,
		0);

	if (!poi)
	{
		puts("Can't allocate Memory!");
		abort();
	}
	
	CopyMemory(poi,tab,96*sizeof(double));

	UnmapViewOfFile((void*)poi);
	CloseHandle(mappedFile);
	CloseHandle(plik);
	getchar();
	return 0;
}

Jednak, nie wiem jak konwertować, by uzyskać czytelne dane w pliku.

0

Proponuje uzyć zwykłego pisania do plików z C++ a nie jakiegoś dzikiego mechanizmu systemowego.

0

Jeśli chcesz by do pliku trafił tekst, to musisz tam umieścić tekst :) Czyli musisz najpierw tą liczbę skonwertować do postaci tekstowej np. przy pomocy ostringstream. Jeśli ten "mechanizm C++" jest niedozwolony ( o_O ) to z WinAPI masz do dyspozycji np. FormatMessage lub wnsprintf StringCchPrintf.

1 użytkowników online, w tym zalogowanych: 0, gości: 1