我有一个打印出树的函数printtree。 我搜索了互联网上的很多地方,我发现mmap是分配内存和写入文件的好方法。
我想使用mmap将printtree的内容打印到文件中。我是第一次学习mmap而且我不知道该怎么做。
printtree()如下:
void printtree(struct Node *root, int indent)
{
int i;
if(root != NULL)
{
printtree(root->right,indent + 1);
for(i = 0;i<indent;i++)
{
printf("\t");
}
printf("%d\n",root->key);
printtree(root->left,indent + 1);
}
}
在我的main.c中,我正在尝试这个:
struct Node *root = NULL;
int info ;
int *arr;
int choice;
int fd;
int mode = 0x0777;
struct stat mystat;
void *p;
int size;
FILE *file_ptr;
if (argc != 2){ printf("Error\nIncorrect number of arguments\n");exit(1);}
if (access(argv[1],F_OK) != -1)
{
fd = open(argv[1],O_RDWR);
if (fd == -1)
{
perror("open");
exit(1);
}
if(fstat(fd, &mystat)<0)
{
perror("fstat");
close(fd);
exit(1);
}
p = mmap(0,mystat.st_size , PROT_READ | PROT_WRITE,
MAP_SHARED ,fd,0);
if(p == MAP_FAILED)
{
perror("mmap");
close(fd);
exit(1);
}
while(1)
{
printf("1.Insert\n");
printf("2.Delete\n");
printf("3.Lookup\n");
printf("4.Print\n");
printf("5.Quit\n");
printf("Enter your choice : ");
scanf("%d",&choice);
switch(choice)
{
case 1:
printf("Enter the value to be inserted : ");
scanf("%d", &info);
//write(fd,&info,36);
if( (root = insert(root,info)) == 0){}
else
break;
case 2:
printf("Enter the value you want to delete : ");
scanf("%d",&info);
root = deleteNode(root,info);
break;
case 4:
printtree(root,0);
break;
//printf("%s",arr[0]);
printf("\n");
break;
case 5:
close(fd);
exit(1);
case 3:
printf("Enter the element you want to look for : ");
scanf("%d",&info);
Search(root,info);
break;
case 6:
printtree(root,0);
break;
default:
printf("Wrong choice\n");
}
}
}
答案 0 :(得分:1)
基本上,地图的初始化看起来很好(即,对mmap
的调用)。您只需要确保映射文件足够大,可能在调用mmap
之前扩展它。查看my answer here以获取有关如何确保内存映射文件足够大的其他信息。
您需要做的下一步是通过写入内存映射文件来替换函数printf
中的printtree
调用。
为此,您可以将文件的内存映射传递给函数,类似于以下示例代码。它使用指针算术处理类似于char[]
的内存映射文件:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
typedef struct Node {
int key;
struct Node* left;
struct Node* right;
} Node;
void printtree(Node* root, int indent, char** mapped_file) {
if(root != NULL) {
printtree(root->left, indent + 1, mapped_file);
int i;
for(i = 0; i < indent; i++) {
**mapped_file = '\t';
(*mapped_file)++;
}
char str[16];
sprintf(str, "%d\n", root->key);
memcpy(*mapped_file, str, strlen(str));
*mapped_file+=strlen(str);
printtree(root->right, indent + 1, mapped_file);
}
}
void main(int argc, const char* argv[] ) {
Node* root = (Node*) malloc( sizeof(Node));
root->key = 1;
root->left = (Node*) malloc( sizeof(Node));
root->left->key = 2,
root->left->left = NULL;
root->left->right = NULL;
root->right = (Node*) malloc( sizeof(Node));
root->right->key = 3;
root->right->left = (Node*) malloc( sizeof(Node));
root->right->left->key = 4;
root->right->left->left = NULL;
root->right->left->right = NULL;
root->right->right = NULL;
printf("%s\n", argv[1]);
int fd = open(argv[1], O_RDWR);
if (fd == -1) {
perror("open");
exit(1);
}
struct stat mystat;
if(fstat(fd, &mystat) < 0) {
perror("fstat");
close(fd);
exit(1);
}
char* mapped_file = (char*) mmap(0, mystat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if(mapped_file == MAP_FAILED) {
perror("mmap");
close(fd);
exit(1);
}
printtree(root, 0, &mapped_file);
}