Home > Software engineering >  Create a Dynamic Array of Vectors Using Malloc
Create a Dynamic Array of Vectors Using Malloc

Time:12-09

Hello I am attempting to learn C , I am trying to use malloc to create an array of vectors but I cannot seem to get it to work. The vectors contain strings. I have no issue making arrays with integers but using vectors has caused me some issues. I am having the same issues with using realloc.

I am trying this, what am I doing wrong?

int buffer_size = 3;
int buffer_count= 0;
vector * words = (string *) malloc(buffer_size * sizeof(string));

//As array of vectors fills up I will add to the buffer count
if(buffer_count => buffer_size){
    words = (string*) realloc(words,buffer_size * sizeof(string));
}

Like I said, I must have something wrong with something in the malloc or realloc function, everything I try gives a variety of errors such as "Use of class template 'vector' requires template arguments.

Thank you for any help.

CodePudding user response:

std::vector and other STL containers are meant to remove the complexities caused by using pointers and dynamic memory allocation, such as memory leaks, undefined behavior invoked by accessing data out-of-bound, etc.

std::vector is dynamic in itself. The more you emplace_back or push_back, the more it grows. If you want a vector that contains strings of variable length, why not declare it like this:

std::vector<String> words {"Hello", "World"};

Similarly, you can create multidimensional vectors:

std::vector<std::vector<Type>> doubleContainer {};

CodePudding user response:

std::vector is a template class, but you are trying to use it without specifying any values for its template arguments. That is why you are getting errors.

However, you can't assign a string* pointer to a vector* pointer, like you are trying to do. Your words variable needs to be declared as string* instead. At least then the code will compile.

However, the code won't behave correctly at runtime, because the malloc()/realloc() functions are from the C runtime library, but std::string is a C non-trivial class that requires construction, and the C functions do not call class constructors. So, you would have to use placement-new to solve that problem (and forget about using realloc(), as there is no safe way to realloc memory that is also placement-new'ed), eg:

string *words = (string*) malloc(buffer_size * sizeof(string));
for (int i = 0; i < buffer_size;   i) {
    new(&words[i]) string;
}
...
if (buffer_count >= buffer_size) {
    int new_buffer_size = buffer_size * 2;
    string *new_words = (string*) malloc(new_buffer_size * sizeof(string));
    for (int i = 0; i < buffer_size;   i) {
        new(&new_words[i]) string(words[i]);
    }
    for (int i = buffer_size; i < new_buffer_size;   i) {
        new(&new_words[i]) string();
    }
    for (int i = 0; i < buffer_size;   i) {
        words[i].~string();
    }
    free(words);
    words = new_words;
    buffer_size = new_buffer_size;
}
...
for (int i = 0; i < buffer_size;   i) {
    words[i].~string();
}
free(words);

In which case, it is better/safer to use new[]/delete[] instead:

string * words = new string[buffer_size];
...
if (buffer_count >= buffer_size) {
    int new_buffer_size = buffer_size * 2;
    string *new_words = new string[new_buffer_size];
    for (int i = 0; i < buffer_size;   i) {
        new_words[i] = words[i];
    }
    delete[] words;
    words = new_words;
    buffer_size = new_buffer_size;
}
...
delete[] words;

Or, just use std::vector properly and let it handle all of the dynamic memory management for you:

vector<string> words;

CodePudding user response:

You're using malloc to allocate memory for a vector of strings, but malloc only allocates raw memory, which means you can't directly use it to create an array of vectors. Instead, you need to use the new keyword.

vector<string> *words = new vector<string>[buffer_size];

You're trying to cast the return value of malloc to a vector*, but this is not allowed. Instead, you can use the vector class's reserve method to allocate the necessary amount of memory for the vectors in the array, and then use the emplace_back method to add new elements to the array.

if (buffer_count >= buffer_size) {
  words->reserve(buffer_size * 2);
  words->emplace_back();
}

Hope this helps!

CodePudding user response:

cout<<sizeof(string)<<endl; have a look

  • Related