2

I need to use some low-level C functions provided by a library, to wrap them and provide a 'more high-level layer' ; in this case , my problem is to get a data contained within a buffer, and at least to learn how to do it right, I would like to know what you think would be the thing to do in C++03 AND in C++11.

FYI, I am working under Red Hat Linux, with GCC 4.4.7 (so not really C++11-compliant, https://gcc.gnu.org/gcc-4.4/cxx0x_status.html).

Here is a snippet of what I am trying to do :

#define DATA_BLOCKS 4096 // the numbers of 16-bit words within the buffer

std::vector<uint16_t> myClass::getData()
{
    uint16_t buffer[DATA_BLOCKS];
    getDataBuf(fd, dma, am, buffer[]); //C-function provided by the library

    // pushing buffer content into vector
    std::vector <uint16_t> myData;
    for(int i=0; i<DATA_BLOCKS; i++)
         myData.pushback(buffer[i]);
    return myData;
}

Within the link I provided, I am not able to find if it's a good idea to proceed like in C++11 to return the 'whole' vector.

For a vector, is there a best method to fill 'myData' than using the method 'pushback()' within a loop ?

2 Answers 2

4

You can do that, it's safe :

std::vector<uint16_t> myClass::getData()
{
    std::vector <uint16_t> myData(DATA_BLOCKS);
    getDataBuf(fd, dma, am, myData.data()); //C-function provided by the library
    // Old interface, before c++11 : getDataBuf(fd, dma, am, &myData[0]);

    return myData;
}

or if you want fill given vector:

void myClass::getData(std::vector<uint16_t> &myData)
{
    myData.resize(DATA_BLOCKS);
    getDataBuf(fd, dma, am, myData.data()); //C-function provided by the library
    // Old interface, before c++11 : getDataBuf(fd, dma, am, &myData[0]);
}

Personnally, I have no opinion about returning vector (which will probably use move semantic) or fill a given vector

EDIT

instead of using vector, because you know precisly the size, you can use std::array<std::uint8_t, DATA_BLOCKS> container (new in C++11). This use is same as vector in my examples

EDIT2

vector and array use contiguous storage locations (reference for vector class), so if you get address from first elements, you can access to the second one by incrementing address. The only dangerous point for vector is to be sure to have allocated memory. In both case, I manage to have enough allocated memory : in first example, vector is instanciate with the fill constructor, and in second one I resize vector to corresponding size. This method is describe in the book "Effective STL - 50 Specific Ways to Improve Your Use of the Standard Template Library" [Scott Meyers]. For array, no problem (on condition to declare array with enough memory of course).

Sign up to request clarification or add additional context in comments.

8 Comments

So, I would have liked to use std::array but my GCC version does not. I provide g++ with the flag '-std=c++0x' just to be sure to use something the nearest possible C++11-compliant (even if it's far from it).
On the other hand, if you can I would like some explanations on your first method because, even if you called it 'safe', not sure how to understand the reference-to-first-case-of-the-array part O_o
Just a silly error of copy/paste but, in your 2nd example, there should be no 'return')
@Paradox 2nd example corrected, and I explain in EDIT2 the reference-to-first-case-of-the-array. I hope it's clear
personally, and to keep the naming consistent with the example, i'd name the vector buffer and then write buffer.data() instead of &buffer[0].
|
1

data() came with C++11. Using it makes the code more ledgibe in my opinion, and aparently others though so too or it wouldn't have been added.

1 Comment

Thanks for the explanation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.