简体   繁体   中英

More effective way to load a std::queue<uint8_t*> with elements?

I am trying to find a more efficient method of loading variable length arrays of uint8_t bytes into a std::queue

The following code snippet is an attempt to reduce the actual code to something more usable as an example; so please forgive me if it's overly complex.

The code snippet works, with the exception of my inability to determine the actual length of each of the elements of the std::queue while they are still at the front of the queue. My question is, "Is there any way to push the pointer to the unsigned byte array into the queue without the intermediate step of creating a local array, copying the passed argument into it and then pushing the local pointer (See comments in code)?

#include <queue>
#include <string>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

using namespace std;

std::queue<uint8_t*> _q;

void routineSubroutine(uint8_t array_a[], int size_a)
{
    /*
     * Is there anyway to push the uint8 array_a into the queue (_q) without
     * creating a new pointer to a byte array, copying the passed
     * argument into it and the pushing it?
     */

    uint8_t* a = new uint8_t[size_a];
    memcpy((void*) a, (const void*) array_a, size_a);
    _q.push(a);
}

int main(int argc, char** argv)
{
    uint8_t myArray[512];

    char cfa[] = {"I wish I was at Chick-Fil-A right now"};
    memset((void*) myArray, 0x00, sizeof (myArray));
    memcpy((void*) myArray, (const void*) cfa, strlen(cfa));
    routineSubroutine(myArray, strlen(cfa));

    char five[] = {"Five Guys will do in a pinch"};
    memcpy((void*) myArray, (const void*) five, strlen(five));
    routineSubroutine(myArray, strlen(five));

    while (_q.size() > 0)
    {
        printf("Queue string value = %s\n", (char*) _q.front());
        /*
         * How do I go about determining the number of bytes in the uint8_t
         * array, whose address is at the front of the queue?
         */
        _q.pop();
    }

    return 0;
}

The code snippet works, with the exception of my inability to determine the actual length of each of the elements of the std::queue while they are still at the front of the queue

Use the proper container that knows its length/size and call the appropriate member function. A mere pointer doesn't do that.

Here is an example of your code rewritten to use std::vector :

#include <queue>
#include <string>
#include <vector>
#include <iostream>

std::queue<std::vector<uint8_t>> _q;

void routineSubroutine(const std::vector<uint8_t>& a)
{
    _q.push(a);
}

int main(int argc, char** argv)
{
    char cfa[] = {"I wish I was at Chick-Fil-A right now"};
    routineSubroutine({std::begin(cfa), std::end(cfa)}); // creates a temp uint8_t vector

    char five[] = {"Five Guys will do in a pinch"};
    routineSubroutine({std::begin(five), std::end(five)}); // creates a temp uint8_t vector

    while ( !_q.empty() )
    {
        // use the `write()` function to control the number of characters
        std::cout.write(reinterpret_cast<const char *>(_q.front().data()), _q.front().size());
        std::cout << "\n";
        _q.pop();
    }
    return 0;
}

Output:

I wish I was at Chick-Fil-A right now
Five Guys will do in a pinch

Ultimately, I have full control over the type of queue I can use, while I have zero control over how the data is presented. Specifically the data is presented as a uint8_t* and size_t length. Thanks to @PaulMcKenie's example code I was able to come up with the following solution (which by the way is wicked fast):

std::queue<std::vector<uint8_t>> myQueue;
while(true)
{
    // Pointer (myBuffer) and length (myLength) magically appear here
    myQueue.push({myBuffer, (uint8_t*) (myBuffer + myLength)});
}

Problem solved.

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