简体   繁体   中英

Pushing an array of pointers into a std::vector avoiding copying the objects with push_back

In this code, an array of pointers newData is created in a for loop then it is pushed into a vector testData . The pointers are stored in the vector std::vector<testData*> .

My concern is that I need to make sure that the objects referenced by the pointers remain valid while the vector holds a reference to them. Do I lose this reference by calling the line newData = new unsigned char[frameSize]; in a for loop?

I mainly want to avoid copying the objects with a push_back .

How can I create an array of unsigned char* of random char (here I just use 'a' ) and then push these arrays to the vector?

int numFrames = 25;
int frameSize = 100;

std::vector<unsigned char*> testData;

unsigned char *newData;

for (int i = 0; i < numFrames; i++) {
    newData = new unsigned char[frameSize];

    for (int j = 0; j < frameSize; j++) {
        newData[j] = 'a'; // fill the frame with random data, 'a' here
    }

    testData.push_back(newData);
    newData = 0; // ??
    memset(&newData, 0, frameSize); // ??
}

std::cout << " testData " << testData.size() << "\n";

Do I lose this reference by calling the line newData = new unsigned char[frameSize]; in a for loop?

No, if done correctly it's perfectly feasible.

The are some problems in your code though, in the line memset(&newData, 0, frameSize); //??memset(&newData, 0, frameSize); //?? you're setting the memory occupied by a pointer, which is usually no more than 8 bytes (depending on the architecture) with a size of 100 bytes, this invokes undefined behavior. You may wanted:

memset(&newData, 0, sizeof newData); // ??

But this wouldn't do what you need, nullifying the pointer would make you lose access to the data, you don't want that, and you are pushing the same pointer to the vector in each iteration, you'll end up with a vector filled with the same pointer pointing to the same data.

Moving its declaration inside the for loop would solve this. You're not copying any data, instead pushing a new pointer, pointing to a new memory location, into the vector, at each new iteration.

How can I create an array of unsigned char* of random char (here I just use 'a' ) and then push these arrays to the vector?`

Your code should look something like this:

Live demo

#include <iostream>
#include <vector>
#include <ctime>
int main()
{   
    srand(time(0)); //seed, not the best randomizer but does the job here
    
    const size_t numFrames = 25; //sizes can/should be constant and unsigned
    const size_t frameSize = 100;

    std::vector<unsigned char *> testData;

    for (size_t i = 0; i < numFrames; i++)
    {
        //in each iteration a new pointer
        unsigned char *newData = new unsigned char[frameSize];

        for (size_t j = 0; j < frameSize; j++)
        {
            newData[j] = 'a' + rand() % 26; //random alphabetic char
        }
        testData.push_back(newData);
    }
    
    std::cout << "testData " << testData.size() << "\n";        
    
    for (size_t i = 0; i < numFrames; i++) //test print
    {
        for (size_t j = 0; j < frameSize; j++)
        {
            std::cout << testData[i][j];
        }
        std::cout << "\n";
    }
}

Needless to say you should delete the memory you previously allocated when you no longer need it.

If you want a better random engine you can check this post Generate random numbers using C++11 random library .

Some notes:

As you're probably aware the data pointed by newData pointers can't be treated as a string, aka, a null terminated char array because, of course, they're not null terminated.

You'll need to manually manage the memory you allocated, that is to say that the memory reserved manually will also have to be deleted manually, when you're done with it.

The code corrections are for your code as it is, but as WhozCraig correctly points out , you would probably be better off using STL containers all around instead of pointers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM