TransWikia.com

SIGABRT on std::ifstream close

Stack Overflow Asked by C0D3 M4513R on November 24, 2021

1I am currently working on a project of creating my own game in OpenGL. My problem is right now, that if I read a file, that my function reading that file results in a SIGABRT, because of something inside the std::ifstream deconstructor (more specifically in "std::basic_ifstream<char, std::char_traits<char> >::~basic_ifstream()"). This function previously worked for me, but suddenly stopped working.

My Goal is simple: A reliable implementation for reading a file to a char*. Multi threading is currently not my concern.

Here is my implementation of the file reading function.
It takes in a path, and should write the content of the file at that path into the out parameter.

#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <cstring>
#include <cassert>
#include "Utility.h"
char * Utility::readFile(const char* path,char*& out){
#ifndef NDEBUG
    std::cout<<"Getting file: "<<path<<"n";
#endif
    // Open the file, but freak out if not valid.
    std::ifstream file=std::ifstream(path);
    assert(file.good());
    if(!file.good())
    {
        throw std::runtime_error((std::string)"Couldn't open file for loading: "+path);
    }

    // Read the file contents into a char buffer.
    std::stringstream buffer;buffer << file.rdbuf();
    std::string fileContentsStr = buffer.str();
    out = new char[fileContentsStr.size()];
    strcpy(out,fileContentsStr.c_str());
    return out;
}

My code is located at C0D3-M4513R/OpenGlGame.
I already tried a minimal example, which is working and using the same compile flags (except linker flags). test.txt and test1.txt just contain some rubbish text generated by randomly hacking on my keyboard.

#include <cassert>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <cstring>

//This Function is the same as the one above!!!
char *readFile(const char *path, char *&out) {
#ifndef NDEBUG
    std::cout << "Getting file: " << path << "n";
#endif
    // Open the file, but freak out if not valid.
    std::ifstream file = std::ifstream(path);
    assert(file.good());
    if (!file.good()) {
        throw std::runtime_error((std::string) "Couldn't open file for loading: " + path);
    }

    // Read the file contents into a char buffer.
    std::stringstream buffer;
    buffer << file.rdbuf();
    //convert the stringstream to a string
    std::string fileContentsStr = buffer.str();
    //copy the contents of the string to a char array
    out = new char[fileContentsStr.size()];
    strcpy(out, fileContentsStr.c_str());
    //return char array address (which should be the same as the start?)
    return out;
}

int main() {
    //The programm started!
    std::cout << "Hello, World!" << std::endl;
    //Define a space for the contents of the file to live
    char *out;
    //Read the contents of a file
    out = readFile("test.txt", out);
    //Print contents of the file
    std::cout << out << std::endl;
    char *out1;
    //Read the contents of a file
    out1 = readFile("test1.txt", out1);
    //Print contents of the file
    std::cout << out1 << std::endl;
    return 0;
}

One Answer

strcpy:

Copies the character string pointed to by src, including the null terminator, to the character array whose first element is pointed to by dest. The behavior is undefined if the dest array is not large enough. The behavior is undefined if the strings overlap.

c_str:

Returns a pointer to a null-terminated character array with data equivalent to those stored in the string.

out = new char[fileContentsStr.size()];
strcpy(out,fileContentsStr.c_str());

You need to be careful when mixing std::string with c-strings, because a std::string is not null-terminated and does not count the nullterminator for its size. However, c_str does return a pointer to a null-terminated character array.

You are asking strcpy to write fileContentsStr.size()+1 (size + null terminator) into a char array with only fileContentsStr.size() elements.

PS: As mentioned in a comment, you should consider to return a std::string instead. You are using a raw owning pointer which is error prone and should be avoided. Either use a smart-pointer or let a std::string manage the char-array (thats what its made for actually ;).

Answered by 463035818_is_not_a_number on November 24, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP