C 使用MapViewOfFile,指针最终会离开内存空间
全部, 我正在使用MapViewOfFile将文件的一部分保存在内存中。有一个流指向该文件并写入该文件,然后被重绕。我使用指向映射文件开头的指针进行读取,直到得到作为最终字符写入的空字符C 使用MapViewOfFile,指针最终会离开内存空间,c,windows,pointers,memory-leaks,mmap,C,Windows,Pointers,Memory Leaks,Mmap,全部, 我正在使用MapViewOfFile将文件的一部分保存在内存中。有一个流指向该文件并写入该文件,然后被重绕。我使用指向映射文件开头的指针进行读取,直到得到作为最终字符写入的空字符 int fd; yyout = tmpfile(); fd = fileno(yyout); #ifdef WIN32 HANDLE fm; HANDLE h = (HANDLE) _get_osfhandle (fd); fm = CreateFileMapping(
int fd;
yyout = tmpfile();
fd = fileno(yyout);
#ifdef WIN32
HANDLE fm;
HANDLE h = (HANDLE) _get_osfhandle (fd);
fm = CreateFileMapping(
h,
NULL,
PAGE_READWRITE|SEC_RESERVE,
0,
4096,
NULL);
if (fm == NULL) {
fprintf (stderr, "%s: Couldn't access memory space! %s\n", argv[0], strerror (GetLastError()));
exit(GetLastError());
}
bp = (char*)MapViewOfFile(
fm,
FILE_MAP_ALL_ACCESS,
0,
0,
0);
if (bp == NULL) {
fprintf (stderr, "%s: Couldn't fill memory space! %s\n", argv[0], strerror (GetLastError()));
exit(GetLastError());
}
数据被发送到yyout
流,直到调用flushData()
。这会将空值写入流,刷新流,然后倒带流。然后我从映射内存的开头开始,读取字符,直到到达null
void flushData(void) {
/* write out data in the stream and reset */
fprintf(yyout, "%c%c%c", 13, 10, '\0');
fflush(yyout);
rewind(yyout);
if (faqLine == 1) {
faqLine = 0; /* don't print faq's to the data file */
}
else {
char * ps = bp;
while (*ps != '\0') {
fprintf(outstream, "%c%c", *ps, blank);
ps++;
}
fflush(outfile);
}
fflush(yyout);
rewind(yyout);
}
刷新后,更多的数据被写入流,这应该设置为内存区域的开始。正如我可以用gdb确定的那样,流没有被重绕,最终会填满分配的空间
由于流指向基础文件,因此最初不会导致问题。但是,当我尝试遍历内存时,我从未找到空值。这将导致一个SIGSEV
。如果你想知道我为什么需要这个的更多细节
为什么我没有按预期重用内存空间?好吧,在做了一段时间之后,我有了一个可行的解决方案。我不知道为什么会成功,所以如果有人想出更好的办法,我会乐意接受他们的答案
fm = CreateFileMapping(
h,
NULL,
PAGE_READWRITE|SEC_RESERVE,
0,
16384,
NULL);
如您所见,唯一的更改是将声明的大小从
4096
更改为16384
。我不知道为什么每次输入的字符总数不超过1200。如果有人能提供这方面的详细信息,我将不胜感激。好吧,在做了一段时间之后,我有了一个可行的解决方案。我不知道为什么会成功,所以如果有人想出更好的办法,我会乐意接受他们的答案
fm = CreateFileMapping(
h,
NULL,
PAGE_READWRITE|SEC_RESERVE,
0,
16384,
NULL);
如您所见,唯一的更改是将声明的大小从
4096
更改为16384
。我不知道为什么每次输入的字符总数不超过1200。如果有人能提供这方面的详细信息,我将不胜感激。我认为MSDN CreateFileMapping文档中的这一行可能就是线索
映射文件和使用输入输出(I/O)函数(ReadFile和WriteFile)访问的文件不一定是一致的
您显然没有使用读/写文件,但是应该从映射视图和显式I/O调用的角度来理解文档。无论如何,C RTL肯定是使用Win32 API实现的
简而言之,这种方法是有问题的
我不知道为什么更改视图/文件大小会有帮助;也许它只是将未定义的行为转移到了一个恰好有益的方向。我认为MSDN CreateFileMapping文档中的这一行可能就是线索 映射文件和使用输入输出(I/O)函数(ReadFile和WriteFile)访问的文件不一定是一致的 您显然没有使用读/写文件,但是应该从映射视图和显式I/O调用的角度来理解文档。无论如何,C RTL肯定是使用Win32 API实现的 简而言之,这种方法是有问题的
我不知道为什么更改视图/文件大小会有帮助;也许它只是将未定义的行为转移到一个恰巧有益的方向。当您完成映射时,只需取消映射即可
UnmapViewOfFile(bp);
完成地图后,只需取消地图
UnmapViewOfFile(bp);
你想达到什么目标?为什么代码不同时取消映射视图并关闭句柄?@STATUS\u ACCESS\u DENIED这只是代码库的一个片段,在使用映射空间后,我取消映射并关闭句柄。关键是将文件流重定向到windows系统上的内存中。您试图实现什么?为什么代码不同时取消映射视图并关闭句柄?@STATUS\u ACCESS\u DENIED这只是代码库的一个片段,在使用映射空间后,我取消映射并关闭句柄。关键是将文件流重定向到windows系统的内存中。我很担心这一点。在这一点上,这件事的工作,我已经没有时间来跟踪这一点。直到它跳起来咬了人。希望我继续前进。当然,除非有人提出解决方案……我很担心。在这一点上,这件事的工作,我已经没有时间来跟踪这一点。直到它跳起来咬了人。希望我继续前进。当然,除非有人想出解决办法。。。