Jump to content
  • Advertisement
Sign in to follow this  
StarikKalachnikov

c++ +memcpy alternative?

This topic is 4607 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
Advertisement
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Well, I want to read the Milkshape format (.ms3d) and in the past I did it like this: (only relevant functions + pseudo code)



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!

Share this post


Link to post
Share on other sites
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:


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-

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!