Array data not saving when pushed into vector

218 views Asked by At

I am creating a custom resource file, however when I set up dummy data and push it onto the containers stack, the values in the array become null. I have an idea as to why it happens(the array data is destroyed when the containing block finishes), but I have no idea on how to prevent it from being destroyed.

#pragma once


#include <vector>
#include <fstream>
#include <stdint.h>

#ifndef __RFNAME
#define __RFNAME "resource.dat"
#endif


using namespace std;

namespace rf {


    struct rfHEADER {
        uint32_t _versionNumber;
    };

    struct rfIMAGE {
        uint32_t _sizeOfData;
        uint32_t *_data;
    };

    struct rfSOUND {

    };

    class rfFILE {

    public:
        //Constructors
        rfFILE() 
        { 
            //Create a dummy header
            HEADER._versionNumber = 16;

            //Create a dummy image
            uint32_t imageArrData[] = {10, 52, 18, 1, 19, 20, 20, 10, 4, 10};
            rfIMAGE i;
            i._sizeOfData = 10;
            i._data = imageArrData;
            IMAGEDATA.push_back(i);

            //Does the data stay when the rfIMAGE data is pushed onto the vector?
            for(int j = 0; j < 10; j++)
            {
                printf("Test image data is: %d\n", IMAGEDATA.front()._data[j]);
            }

        }
        ~rfFILE() { }

        void test()
        {
            //Modify dummy data
            HEADER._versionNumber = 9;

            rfIMAGE i = IMAGEDATA.front();

            uint32_t imageArrData[] = {0};
            i._data = imageArrData;
            i._sizeOfData = 1;

            IMAGEDATA.front() = i;

        }

        void printVersionNumber() {
            printf("The current version number is... %d\n", HEADER._versionNumber);


            printf("The image data size is... %d\n", IMAGEDATA.front()._sizeOfData);
            printf("The image data is...\n");
            for(uint32_t i = 0; i < IMAGEDATA.front()._sizeOfData; i++)
            {
                printf("%d\t", IMAGEDATA.front()._data[i]);
            }

        }

        //Reads from a resource file
        void readFromFile()
        {
            //set the resource file name
            const char* filename = __RFNAME;

            //Set up the instream
            ifstream iStream;
            iStream.open(filename, ios_base::binary);

            //If the instream is open
            if(iStream.is_open()) {
                //Read the first 4 bytes into the header
                iStream.read((char*)&HEADER, sizeof(HEADER));




                //close the instream
                iStream.close();
            }

        }

        //Write to a resource file
        void writeToFile()
        {
            //set the resource file name that we will be writing to
            const char* fileName = __RFNAME;
            //Set up the outstream
            ofstream oStream;
            oStream.open(fileName, ios_base::binary);

            //if the stream is open
            if(oStream.is_open()) {

                //write the header
                oStream.write((char*)&HEADER, sizeof(HEADER));

                //Write how many elements are in the IMAGEDATA stack (4 bytes)
                oStream.write((char*)IMAGEDATA.size(), sizeof(IMAGEDATA.size()));
                //Loop through n times and write the image data, where n is the number of elements in IMAGEDATA
                for(int i = 0; i < IMAGEDATA.size(); i++) {
                    uint32_t datasize = IMAGEDATA[i]._sizeOfData;
                    oStream.write((char*)IMAGEDATA[i]._sizeOfData, sizeof(IMAGEDATA[i]._sizeOfData));
                    oStream.write((char*)IMAGEDATA[i]._data, datasize);
                }

                //Close the stream
                oStream.close();
            }



        }



    private:
        rfHEADER HEADER;
        vector<rfIMAGE> IMAGEDATA;
        vector<rfSOUND> SOUNDDATA;

    protected:
        rfFILE(const rfFILE& copy) { }
    };
}

Any ideas on how to keep the values put into the dummy rfIMAGE and pushed onto the vector after the block the dummy data is declared in leaves scope?

2

There are 2 answers

9
merlin2011 On

Instead of allocating on the stack, try allocating your data on the heap instead. Stack data is effectively gone when the code block in which it was allocated finishes.

Replace this line:

uint32_t imageArrData[] = {10, 52, 18, 1, 19, 20, 20, 10, 4, 10};

With the following, and then assign your elements.

uint32_t* imageArrData = new uint32_t[10];
imageArrData[0] = 10;
imageArrData[1] = 52;
...
1
πάντα ῥεῖ On

You should provide your imageArrData dummy as static function local variable in your constructor, otherwise the data goes out of scope as soon the constructor function is left:

//Constructors
rfFILE() { 
   //Create a dummy header
   HEADER._versionNumber = 16;

   //Create a dummy image
   static uint32_t imageArrData[] = {10, 52, 18, 1, 19, 20, 20, 10, 4, 10};
// ^^^^^^

UPDATE
Another (better) option is to hold your whole image data in a std::vector<uint32_t> instead of using a plain pointer and size, e.g.:

typedef std::vector<uint32_t> rfIMAGE;

To interact with raw uint32_t* data pointers given along with a size_t size parameter, you can use the std::vector<>::assign() method:

rfIMAGE image;

void setImage(uint32_t* imgData, size_t imgSize) {
    assert(imgData);
    image.assign(imgData,imgData + imgSize);
}