c++ +memcpy alternative?
Hi,
Just a short question, I read files the C++ way (fstreams and such) and have a function that returns a char* since ifstream.read uses char* as an out parameter.
I then process the data with memcpy, e.g. memcpy(&header.id, buffer, sizeof(int)). Now I need to know if I'm on the right track, performance wise and C++ wise, like, is there a C++ way of getting the data out of char* buffer?
I hope you can understand my question, :)
Starik
Performance-wise: ifstream already uses an internal buffer, so loading everything into your own buffer before processing it is awkward and redundant in many cases. Why not directly read the data into the object?
Design-wise: in my opinion, you should create friend function (member or external) to serialize objects. This will allow you to implement loading systems that go beyond the simple "copy the memory". Also, everything you might one day need is already implemented in a very performant way as part of the boost::serialize library.
Design-wise: in my opinion, you should create friend function (member or external) to serialize objects. This will allow you to implement loading systems that go beyond the simple "copy the memory". Also, everything you might one day need is already implemented in a very performant way as part of the boost::serialize library.
If it's an alternative to memcpy() you're looking for, #include <algorithm> and use std::copy(). You could also try to have the stream directly place the data in its ultimate destination rather than in an intermediary buffer.
Or maybe I don't understand what you're trying to do.
Or maybe I don't understand what you're trying to do.
Well, I want to read the Milkshape format (.ms3d) and in the past I did it like this: (only relevant functions + pseudo code)
I don't have access to my code right now, so there are probably errors in it, and maybe the code style is even worse, which is what I'm trying to figure out.
But what I understand right now is that I need to modify my classes, add a function with a parameter (stream)(probably make an abstract base class for consistency), and read the appriate data present?
Do you have any examples I can look at?
Thanks so far!
ReadModel(std::string aFilename){ ifstream file(aFileName.c_str(), ios::binary); file.seekg(0, ios::end); int length = file.tellg(); file.seekg(0, ios::beg); char* buffer = new char[length]; file.read(buffer, length); ms3dHeader header; //milkshape header class with public members :( memcpy(&header.id, buffer, sizeof(int)); buffer += sizeof(int); memcpy(&header.version, buffer, sizeof(char) * 10); buffer += sizeof(char) * 10; int vertexCount = 0; memcpy(&vertexCount, buffer, sizeof(word)); buffer += sizeof(word); //and so on... }
I don't have access to my code right now, so there are probably errors in it, and maybe the code style is even worse, which is what I'm trying to figure out.
But what I understand right now is that I need to modify my classes, add a function with a parameter (stream)(probably make an abstract base class for consistency), and read the appriate data present?
Do you have any examples I can look at?
Thanks so far!
Just as ToohrVyk has pointed out, you are needlessly loading the entire file into an intermediate buffer. You can instead directly use the istream interface to read the data:
However, performance-wise, the iostream library is not so great for binary data because of the inefficient internal buffering approach. Of course this varies with the implementation you use, but any valid implementation of the standard libraries is required to provide the entire chain down to the std::streambuf.
-Markus-
struct MilkshapeHeader { int id; char version[10]; short vertexCount; friend std::istream &operator >>(std::istream &i, MilkshapeHeader &header) { i.read(reinterpret_cast<char *>(&header.id), sizeof(header.id)); i.read(reinterpret_cast<char *>(&header.version), sizeof(header.version)); i.read(reinterpret_cast<char *>(&header.vertexCount), sizeof(header.vertexCount)); return i; }};int main() { MilkshapeHeader header; std::ifstream("test.milkshapemodel", std::ios::binary) >> header;}
However, performance-wise, the iostream library is not so great for binary data because of the inefficient internal buffering approach. Of course this varies with the implementation you use, but any valid implementation of the standard libraries is required to provide the entire chain down to the std::streambuf.
-Markus-
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement