Blademoon
Blademoon

Reputation: 109

Linux API and C++ STD vector

How safe and correct is it to use a vector (vector unsigned char) instead of a character array (char []) when interacting with the file system using linux api (read,write)? Constructive criticism is needed. Are there any other alternatives?

I want to use this technique when writing a wrapper library (using classes).

Code example:

// This program was written to test the possibility of using a vector as a buffer
// for reading and writing to a file using linux api.

#include <iostream>
#include <vector>

#include <fcntl.h>      // Linux API open
#include <unistd.h>     // Linux API read,write,close

using namespace std;

int main() {
    vector <unsigned char> buffer(10);

    buffer[0] = '1';
    buffer[1] = '2';
    buffer[2] = '3';
    buffer[3] = '4';
    buffer[4] = '5';
    buffer[5] = '5';
    buffer[6] = '4';
    buffer[7] = '3';
    buffer[8] = '2';
    buffer[9] = '1';

    // Open new file for writing (create file)
    int fd = 0;
    const char *path = "./test.txt";

    fd = (open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU));

    if (fd == -1) {
        cout << "Can't open (create) file!!!" << endl;
        return 0;
    }

    // Write to file from vector
    write(fd, &buffer, buffer.size());

    // Close file
    close(fd);

    // Open file for reading
    fd = open(path, O_RDONLY);

    vector <unsigned char> buffer1(10);

    // Read from file to vector
    read (fd,&buffer1,buffer1.size());

    // close file
    close(fd);

    return 0;
}

Upvotes: 2

Views: 1125

Answers (1)

πάντα ῥεῖ
πάντα ῥεῖ

Reputation: 1

Regarding your doubts and questions

How safe and correct is it to use a vector (vector unsigned char) instead of a character array (char []) when interacting with the file system using linux api (read,write)?

It's totally safe to use std::vector<uint8_t>, std::array<uint8_t,const_size>, std::string with API functions which expect a contiguous (null terminated in case of std::string) array of either unsigned char[] or char[].

All of these classes mentioned above provide a data() member that allows to access the underlying data directly.

Are there any other alternatives?

Yes there are other alternatives to manage these pointers more manually, e.g. std::unique_ptr or std::shared_ptr, but usually you don't need them.

I want to use this technique when writing a wrapper library (using classes).

That's a common, flexible and robust technique to create such API wrapper classes.


Regarding your example code

// Write to file from vector
write(fd, &buffer, buffer.size());

and

// Read from file to vector
read (fd,&buffer1,buffer1.size());

are wrong, because &buffer(1) doesn't point to the address of the underlying data managed by the std::vector class.

You'll need to use the std::vector<T>::data() function to access that pointer to the underlying data:

// Write to file from vector
write(fd, buffer.data(), buffer.size());

// Read from file to vector
read (fd,buffer1.data(),buffer1.size());

Constructive criticism is needed. Are there any other alternatives?

In your specific case it seems you want primarily text to be written and read from the underlying file. In this case I'd prefer to use std::string instead of the std::vector<unsigned char>.

That makes it easier to write stuff like

std::string buffer = "123455432";

for the data initialization.

Upvotes: 1

Related Questions