C 使用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(

全部,

我正在使用MapViewOfFile将文件的一部分保存在内存中。有一个流指向该文件并写入该文件,然后被重绕。我使用指向映射文件开头的指针进行读取,直到得到作为最终字符写入的空字符

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系统的内存中。我很担心这一点。在这一点上,这件事的工作,我已经没有时间来跟踪这一点。直到它跳起来咬了人。希望我继续前进。当然,除非有人提出解决方案……我很担心。在这一点上,这件事的工作,我已经没有时间来跟踪这一点。直到它跳起来咬了人。希望我继续前进。当然,除非有人想出解决办法。。。