2011-07-13 42 views
2

一段时间以来,我一直在尝试使用C++将内存写入文件缓冲区时遇到了一个非常奇怪的问题。这个问题只发生在MinGW上。当我在gcc/linux下编译时,一切都很好。如何将内存写入文件缓冲区进行变异?

Debugging Session displaying the problem

所以基本上,我正在写从内存缓冲区代码为filebuffer,并在文件中的二进制表示最终被从我写的内存不同。不,该文件稍后没有被修改,我通过在关闭文件后使用调试器退出程序来保证这一点。我不知道这样的事情甚至是可能的,我甚至用valgrind来查看是否有任何内存分配问题,但不是。

我会粘贴一些相关的代码。

/// a struct holding information about a data file 
class ResourceFile { 
public: 
    string name; 
    uint32 size; 
    char* data; 

    ResourceFile(string name, uint32 size); 
}; 

ResourceFile::ResourceFile(string name, uint32 size) 
    : name(name), size(size) 
{ 
    // will be free'd in ResourceBuilder's destruction 
    data = (char*) malloc(size * sizeof(char)); 
} 


/// Build a data resource from a set of files 
class ResourceBuilder { 
public: 
    ofstream out; ///< File to put the resource into 
    vector<ResourceFile> input; ///< List of input strings 

    /// Add a file from disk to the resource 
    void add_file(string filename); 

    /// Create a file that the resource will be written to 
    void create_file(string filename); 

    ~ResourceBuilder(); 
}; 

void ResourceBuilder::create_file(string filename) { 
    // open the specified file for output 
    out.open(filename.c_str()); 
    uint16 number_files = htons(input.size()); 
    out.write((char*) &number_files, sizeof(uint16)); 

    foreach(vector<ResourceFile>,input,i) { 
     ResourceFile& df = *i; 
     uint16 name_size = i->name.size(); 
     uint16 name_size_network = htons(name_size); 
     out.write((char*) &name_size_network, sizeof(uint16)); 
     out.write(i->name.c_str(),name_size); 
     uint32 size_network = htonl(i->size); 
     out.write((char*) &size_network, sizeof(i->size)); 
     out.write(i->data, i->size); 
    } 

    out.close(); 

    /// \todo write the CRC 
} 

以下是如何分配内存的第一个地方。这是一个可能的错误来源,因为我从别处拷贝了它而没有详细地理解它,但我真的不知道如何分配内存的方法可能是文件缓冲区输出不同于内存的原因我正在写作。

void ResourceBuilder::add_file(string filename) { 
    // loads a file and copies its content into memory 
    // this is done by the ResourceFile class and there is a 
    // small problem with this, namely that the memory is 
    // allocated in the ResourceFile directly, 
    ifstream file; 
    file.open(filename.c_str()); 

    filebuf* pbuf=file.rdbuf(); 

    int size=pbuf->pubseekoff (0,ios::end,ios::in); 
    pbuf->pubseekpos (0,ios::in); 

    ResourceFile df(filename,size); 

    pbuf->sgetn (df.data,size); 

    file.close(); 

    input.push_back(df); 
} 

我真的没有想法。这也不是与我的编译器设置有关的错误,因为编译MinGW下的代码的其他人也会得到相同的错误。我现在唯一能想到的解释是MinGW的filebuffer库本身存在一个bug,但我真的不知道。

+0

量子力学! –

回答

5

您需要以二进制模式打开文件。当您在Windows上以文本模式打开它时,换行符(0x0A)将转换为CR/LF对(0x0D,0x0A)。在Linux上,您不会看到这一点,因为Linux在文本文件中使用单个LF(0x0A)作为行终止符,因此不会进行转换。

传递ios::binary标志的ostream::open方法:

out.open(filename.c_str(), ios::out | ios::binary); 

读取二进制文件时,所以不执行相反的转换,也应当使用这个标志:

ifstream file; 
file.open(filename.c_str(), ios::in | ios::binary); 
+0

* facepalms *哦该死的,现在我觉得很蠢。看那段代码的时间,并忽略这样一个简单的事情..无论如何,谢谢!这固定好了。太糟糕了,我不能接受两个答案,因为你们两个在同一时间回答。 – cib

+0

@cib它发生在每个人身上,我发誓:P –

2

问题是你在文本模式下打开你的文件!在这种情况下,0x0a(换行)转换为0x0d0a(回车换行)。这就是您看到文件和内存有所不同的原因。

使用out.open(filename.c_str(), ios::binary | ios::out);

相关问题