Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Program crashes when getting buffer for audio file  (Read 3998 times)

0 Members and 1 Guest are viewing this topic.

AdventWolf

  • Jr. Member
  • **
  • Posts: 54
    • View Profile
Program crashes when getting buffer for audio file
« on: January 11, 2011, 03:02:15 am »
I've been trying to work this out for a while but I keep getting errors or the program crashes. I have no idea why it is crashing, I'm using pretty much the same method as the sample from the tutorial here. http://sfml-dev.org/wiki/en/tutorials/formatdat

Code: [Select]
class AudioDAT
{
private :
    sAudioDATHeader m_header; /// file header
    std::vector<sAudioEntry> m_entries; /// vector of files entries
    char* m_buffer; /// Buffer pointing on a file in memory
public :
...
    long int GetAudioSize (std::string filename);
};


Code: [Select]
//In AudioDAT.cpp
char* AudioDAT::GetAudio (std::string filename)
{
    //The input file stream from which we want information
    std::ifstream datfile;
 
    //Cleaning properly an ancient file loaded
    if (m_buffer != NULL) //Program crashes here
    {
        delete (m_buffer);
        m_buffer = NULL;
    }

    //First, we have to find the file needed
    for (unsigned int i=0; i<m_header.nb_files;i++)
    {
        //If we found it
        if (m_entries[i].name == filename)
        {
            //We are allocating memory to the buffer
            m_buffer = new char[(m_entries[i].size)];
            //Simple error catch
            if (m_buffer==NULL)
                return (NULL);
            //Opening the DAT file ot read the file datas needed
            datfile.open (m_datfile.c_str(), std::ifstream::in | std::ifstream::binary);
            if (datfile.is_open())
            {
                //Going to the right position
                datfile.seekg (m_entries[i].offset, std::ios::beg);
                //Reading
                datfile.read (m_buffer, m_entries[i].size);
                //We can close the DAT file
                datfile.close();
                //Returning the buffer
                return (m_buffer);
            }
        }
    }
    //Finally, there is no such file in our DAT file
    return (NULL);
}
...
long int AudioDAT::GetAudioSize (std::string filename)
{
    //First, we have to find the file needed
    for (unsigned int i=0; i<m_header.nb_files;i++) //Also crashes here
    {
        //If we found it
        if (m_entries[i].name == filename)
        {
            //Returning the size of the file found
            return (m_entries[i].size);
        }
    }
    return (0);
}


Code: [Select]
class AudioManager
{
std::vector<std::string> audio_container;

public:
AudioManager();
        AudioDAT data;
char * GetBuffer(std::string name);
long int GetSize(std::string name);
}


Code: [Select]
//In AudioManager.cpp
char* AudioManager::GetBuffer(std::string name)
{
char* buffer = data.GetAudio(name); //Crashes here
if (buffer == NULL)
    {
        std::cout<<"Read error"<<std::endl;
    }
return buffer;
}

long AudioManager::GetSize(std::string name)
{
return data.GetAudioSize(name);
}


Code: [Select]
//In application of code
//AUDIO is AudioManager
char* buffer = AUDIO.GetBuffer("Data/Audio/x1.ogg");//crashes here
long int size = AUDIO.data.GetAudioSize("Data/Audio/x1.ogg");//crashes here
        MenuSong.OpenFromMemory(buffer,size);

AdventWolf

  • Jr. Member
  • **
  • Posts: 54
    • View Profile
Program crashes when getting buffer for audio file
« Reply #1 on: January 13, 2011, 11:22:03 pm »
It is crazy, I have had a working dat file for the images i my program so I just copied all of the code and made a new class and just renamed it and switched "Image" to "Audio". It is the same exact code but when I I try to execute this:

Code: [Select]
char* buffer0 = IMAGES.data.GetImage("Data/Images/test.png");
char* buffer  = AUDIO.data.GetImage("Data/Images/test.png");


No matter how I switch the code around, it only crashes on the Audio Version. I'm not even loading audio, I'm just trying to load the same image. The code is exactly the same! I just don't understand what the problem is.

EDIT: For some reason in this function
Code: [Select]
char* AudioDAT::GetImage (std::string filename)
{
    //The input file stream from which we want information
    std::ifstream datfile;
    //Cleaning properly an ancient file loaded
    //if (m_buffer != NULL)
    //{
    //    delete (m_buffer);
    //    m_buffer = NULL;
    //}
std::cout << m_entries[1].name << std::endl;
    //First, we have to find the file needed
    /*for (unsigned int i=0; i<m_header.nb_files;i++)
    {
        //If we found it
        if (m_entries[i].name == filename)
        {
            //We are allocating memory to the buffer
            m_buffer = new char[(m_entries[i].size)];
            //Simple error catch
            if (m_buffer==NULL)
                return (NULL);
            //Opening the DAT file ot read the file datas needed
            datfile.open (m_datfile.c_str(), std::ifstream::in | std::ifstream::binary);
            if (datfile.is_open())
            {
                //Going to the right position
                datfile.seekg (m_entries[i].offset, std::ios::beg);
                //Reading
                datfile.read (m_buffer, m_entries[i].size);
                //We can close the DAT file
                datfile.close();
                //Returning the buffer
                return (m_buffer);
            }
        }
    }*/
std::cout << "END" << std::endl;
    //Finally, there is no such file in our DAT file
    return (NULL);
}
It won't recognize the variables of the class, if I try to use m_buffer it just crashes, if I try to use m_entries, it crashed, anything to do with the class just crashes. I can clearly see the variables are inside the class, plus it is the same code as the other class, except renamed. Why would it do that?

devlin

  • Full Member
  • ***
  • Posts: 128
    • View Profile
Program crashes when getting buffer for audio file
« Reply #2 on: January 14, 2011, 09:12:19 am »
Just a wild stab in the dark, but have you created your AudioDAT and/or AudioDAT.data object properly?

AdventWolf

  • Jr. Member
  • **
  • Posts: 54
    • View Profile
Program crashes when getting buffer for audio file
« Reply #3 on: January 14, 2011, 05:32:40 pm »
Yeah, data is the same for both of the classes. data is just the DAT class that holds creates the DAT file. AUDIO and IMAGES are the managers of the data. But going through the debugger some more I see it crashes inside the vector:

Code: [Select]
//line726
                        size_type size() const
{ // return length of sequence
return (_Mylast - _Myfirst); //crashes here
}


Code: [Select]
#if _HAS_ITERATOR_DEBUGGING
if (size() <= _Pos) //crashes here
{
_DEBUG_ERROR("vector subscript out of range");
_SCL_SECURE_OUT_OF_RANGE;
}
 #endif /* _HAS_ITERATOR_DEBUGGING */


It looks like it crashes because of the size of the vector, but it is definitely not the problem.
It just seems as if the variables go out of scope inside the "GetImage" function.

I got this error when trying to run the program:
Code: [Select]
_block_type_is_valid phead- nblockuse
I read up on it and it seems like it happens when a program is trying to access a pointer to char that has been deleted, but the setup of the class is exactly the same as the other class so I don't know why the other hasn't given me any problems.

EDIT: I deleted the class, and now the other working DAT class is giving me the error.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Program crashes when getting buffer for audio file
« Reply #4 on: January 14, 2011, 07:21:55 pm »
Reduce your code to a minimal and complete example that still reproduces the problem.

By the way, the error-proneness sinks rapidly when you use modern C++ (and RAII in particular) – that is, std::vector instead of new char[size].
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

AdventWolf

  • Jr. Member
  • **
  • Posts: 54
    • View Profile
Program crashes when getting buffer for audio file
« Reply #5 on: January 14, 2011, 10:08:00 pm »
I deleted all of the files and removed the evidence of the dat files and re-made the files. So far the Image one works perfectly and I am trying to manage the audio version.

The name of the audio file is MenuSong.ogg.

I've got this error:
Code: [Select]
SoundManager::LoadSound(sf::Music * temp=0x00000000, std::basic_string<char,std::char_traits<char>,std::allocator<char> > sound_id="Data/Audio/MenuSong.ogg")  Line 46 C++


Code: [Select]
//sf::Music* MenuSong
SOUND.LoadSound(MenuSong,"Data/Audio/MenuSong.ogg");


Code: [Select]
void SoundManager::LoadSound(sf::Music* temp, std::string sound_id)
{
temp_data = data.GetSound(sound_id); //char* temp_data
temp_size = data.GetSoundSize(sound_id); //char* temp_size
if(temp_data == NULL)
{
std::cout << "Error Loading... " << sound_id << std::endl;
}
else
{
temp->OpenFromMemory(temp_data, temp_size);
}
}


These are the data functions:

Code: [Select]
char* SoundDAT::GetSound (std::string file_id)
{
    //The input file stream from which we want information
    std::ifstream datfile;
 
    //Cleaning properly an ancient file loaded
    if (m_buffer != NULL)
    {
        delete (m_buffer);
        m_buffer = NULL;
    }
 
    //First, we have to find the file needed
    for (unsigned int i=0; i<m_header.nb_files;i++)
    {
std::cout << "ID: " << file_id << std::endl;
std::cout << "i: " << m_entries[i].name << std::endl;
        //If we found it
if (m_entries[i].name == file_id)
        {
            //We are allocating memory to the buffer
            m_buffer = new char[(m_entries[i].size)];
            //Simple error catch
            if (m_buffer==NULL)
                return (NULL);
            //Opening the DAT file ot read the file datas needed
            datfile.open (m_datfile.c_str(), std::ifstream::in | std::ifstream::binary);
            if (datfile.is_open())
            {
                //Going to the right position
                datfile.seekg (m_entries[i].offset, std::ios::beg);
                //Reading
                datfile.read (m_buffer, m_entries[i].size);
                //We can close the DAT file
                datfile.close();
                //Returning the buffer
std::cout << "RETURNING BUFFER" << std::endl;
std::cout << "BUFFER: " << m_buffer << std::endl;
                return (m_buffer);
            }
        }
    }
    //Finally, there is no such file in our DAT file
std::cout << "RETURN NULL" << std::endl;
    return (NULL);
}

long int SoundDAT::GetSoundSize (std::string file_id)
{
    //First, we have to find the file needed
    for (unsigned int i=0; i<m_header.nb_files;i++)
    {
        //If we found it
        if (m_entries[i].name == file_id)
        {
            //Returning the size of the file found
            return (m_entries[i].size);
        }
    }
    return (0);
}


The program crashes at the end of the LoadSound function.
Though if I don't use pointers and I just put this:
Code: [Select]
sf::Music temp1;
temp1.OpenFromMemory(temp_data,temp_size);

Then it doesn't crash. However if I switch out the sf::Music* temp with sf::Music temp inside the function definitions, then I get the noncopyable error when trying to compile:
Code: [Select]
error C2248: 'sf::NonCopyable::NonCopyable' : cannot access private member declared in class 'sf::NonCopyable'

Silvah

  • Guest
Program crashes when getting buffer for audio file
« Reply #6 on: January 14, 2011, 11:36:32 pm »
Quote from: "Nexus"
By the way, the error-proneness sinks rapidly when you use modern C++ (and RAII in particular) – that is, std::vector instead of new char[size].
If only there were a way to make std::vector not initialize its elements... Why one have to pay for setting them to zeros if the only thing that happens with these zeros is simply overwriting them several lines later?

AdventWolf

  • Jr. Member
  • **
  • Posts: 54
    • View Profile
Program crashes when getting buffer for audio file
« Reply #7 on: January 15, 2011, 12:16:58 am »
I finally got it, thank God for pointers.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Program crashes when getting buffer for audio file
« Reply #8 on: January 15, 2011, 12:30:17 am »
Quote from: "AdventWolf"
The program crashes at the end of the LoadSound function.
Before you dereference pointers, you have to initialize them. Otherwise, the behaviour is undefined. MenuSong is not initialized.

Code: [Select]
If only there were a way to make std::vector not initialize its elements... Why one have to pay for setting them to zeros if the only thing that happens with these zeros is simply overwriting them several lines later?That's indeed a pity. Unfortunately, there are a some places in the C++ standard library that are far from optimal (for example specifications when to use swap in STL implementations).

However, that's usually not the reason to abandon std::vector. I really doubt the speed is a concern here. And even if it were, it would be more important to write the program correctly. Especially when one's not very experienced with manual memory management, std::vector is the far better choice, when real projects and not just experiments are in play.

And apart from all that, one can still write or search for a small buffer class, if this is a often-needed functionality. ;)

Quote from: "AdventWolf"
I finally got it, thank God for pointers.
When you really want to continue using raw pointers, you should spend some time on understanding how they exactly work. But even with a good understanding, you should prefer RAII where possible. Believe me, it makes your life a lot easier.

Then you also get rid of silly constructs like this :)
Code: [Select]
if (m_buffer != NULL)
    {
        delete (m_buffer);
        m_buffer = NULL;
    }
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development: