使用MapViewOfFile,指针最终走出内存空间

所有,

我正在使用MapViewOfFile在内存中保存文件的一部分。 有一个stream指向这个文件,并写入它,然后倒带。 我使用指向映射文件的开始的指针,并阅读,直到我得到作为最终字符的空字符。

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()); } 

数据被发送到yyoutstream,直到flushData()被调用。 这写入一个空的stream,刷新,然后回滚stream。 然后,我从映射内存的开始处开始读取字符,直到达到空值。

 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); } 

在刷新之后,更多的数据被写入stream,应该被设置为存储区的开始。 就像我可以用gdb确定的那样,stream不会被倒回,并最终填满分配的空间。

由于stream指向底层文件,所以最初不会导致问题。 但是,当我试图走内存,我从来没有find空。 这导致了一个SIGSEV 。 如果你想知道为什么我需要这个更多的细节, 请看这里 。

为什么我不按预期重用内存空间?

我认为从MSDN文档的CreateFileMapping这行可能是线索。

映射文件和通过使用输入和输出(I / O)函数(ReadFile和WriteFile)访问的文件不一定是连贯的。

你显然没有使用Read / WriteFile,但是应该根据映射视图和显式I / O调用来理解文档。 无论如何,C RTL肯定是使用Win32 API实现的。

总之,这种方法是有问题的。

我不知道为什么改变视图/文件的大小有帮助; 也许它只是把不确定的行为转向有益的方向。

那么,在这个工作一段时间后,我有一个工作的解决方案。 我不知道为什么这个成功,所以如果有人提出更好的东西,我会很乐意接受他们的答案。

 fm = CreateFileMapping( h, NULL, PAGE_READWRITE|SEC_RESERVE, 0, 16384, NULL); 

正如你所看到的,唯一的变化就是从409616384的大小。 为什么这个功能一次输入的字符总数不超过1200,我不知道。 如果有人能提供这方面的细节,我将不胜感激。

完成地图后,只需将其取消映射即可。

 UnmapViewOfFile(bp);