0

I am trying to serialize several text files and I have a function like this:

void to_file_px(Ciphertext* encryptedPx, int index) {
    // Serialize Pixel i

    //red
    filebuf* fbCipherR; // EDIT: THIS LINE IS PROBLEMATIC
    string* filenameR = new string("../serialization/pixels/px" + to_string(index) + "R.txt");
    fbCipherR -> open((*filenameR).c_str(), std::ios::out|std::ios::binary);
    ostream* osCipherR = new ostream(fbCipherR);
    encryptedPx[0].Ciphertext::save((*osCipherR));
    fbCipherR -> close();
    delete filenameR;
    delete fbCipherR;
    delete osCipherR;

    //green

    //blue

    delete[] encryptedPx;
}

However, this function causes an error as Segmentation fault (core dumped).

May I know what exactly causes the error?

Note: Ciphertext::save comes from Microsoft SEAL


OK, I made a mistake. I didn't initialize filebuf*.

So I changed filebuf* fbCipherR = new filebuf(); and I got a new error message:

terminate called after throwing an instance of 'std::runtime_error'
  what():  I/O error
Aborted (core dumped)
Yunus Temurlenk
  • 4,085
  • 4
  • 18
  • 39
Taihouuuuuuuuuuu
  • 87
  • 2
  • 2
  • 10
  • You didn't allocate the filebuf. – David G Jan 21 '20 at 06:35
  • 2
    `fbCipherR` is an uninitialized pointer when you dereference it. Why in the world are you using raw pointers and `new` everywhere? C++ is not Java and there's no reason for all of this manual memory management.. – Blastfurnace Jan 21 '20 at 06:35
  • @Blastfurnace because this function will be called for thousands of times... I don't want some memory leaks – Taihouuuuuuuuuuu Jan 21 '20 at 06:36
  • 4
    Using raw pointers and `new` is how you create memory leaks and segfaults. There's no reason for `new` here and just using actual objects and values will solve these problems. Again, C++ is not Java and you should stop trying to write Java-style code. – Blastfurnace Jan 21 '20 at 06:39
  • I modified my code and got a new error. – Taihouuuuuuuuuuu Jan 21 '20 at 06:40
  • Please read https://ericlippert.com/2014/03/05/how-to-debug-small-programs/ . – Sneftel Jan 21 '20 at 06:50
  • 1
    You need to unlearn a lot of Java. There is a list of good books [here](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – molbdnilo Jan 21 '20 at 06:56
  • Is there a reason you're using `filebuf` directly rather than `ofstream`? – Alan Birtles Jan 21 '20 at 07:23

3 Answers3

2

You should allocate your variables in stack instead of heap, because then they are default constructed and automatically destructed.

filebuf fbCipherR;
string filenameR = "../serialization/pixels/px" + to_string(index) + "R.txt";
fbCipherR.open(filenameR.c_str(), std::ios::out|std::ios::binary);
ostream osCipherR(fbCipherR);
encryptedPx[0].Ciphertext::save(osCipherR);
fbCipherR.close();

Your program is terminated because there is an uncaught exception. You should handle exceptions in every thread. How to catch exceptions.

VLL
  • 9,634
  • 1
  • 29
  • 54
1

Your exception is possibly due to a failure opening the file, you should check the state of the buffer/stream before using it.

You can probably simplify your code by using ofstream rather than filebuf and by putting everything on the stack rather than heap allocating:

void to_file_px(Ciphertext* encryptedPx, int index) {
    // Serialize Pixel i

    //red
    string filenameR = "../serialization/pixels/px" + to_string(index) + "R.txt";
    ofstream osCipherR(filenameR.c_str(), std::ios::out|std::ios::binary);
    if (!osCipherR)
    {
       std::cout << "error opening output file\n";
    }
    else
    {
        encryptedPx[0].Ciphertext::save(osCipherR);
    }

    //green

    //blue

    delete[] encryptedPx;
}
Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
0

Try initialize the filebuf using this method.

 std::ifstream is;
 std::filebuf * fb = is.rdbuf();

 fb->open ("test.txt",std::ios::out|std::ios::app);

 // >> appending operations here <<

 fb->close();

And for string you do not need to create a pointer to string since you are just using the string in this function, just write like this will do

   //string* filenameR = new string("../serialization/pixels/px" + to_string(index) + "R.txt");
   //use a local variable string instead of a "new" string since you are not using this string anymore after this function
  string filenameR = "../serialization/pixels/px" + to_string(index) + "R.txt";
pengMiao
  • 324
  • 1
  • 6