1

We are given:

typedef const char* V;
typedef std::vector<V> Record;

We instantiate the record somewhere in code like:

Record rec;

We populate it with data via malloc:

void fixed_len_read(void *buf, int size, Record *record){
    char *c_buf = (char *)malloc(size);
    memcpy(c_buf, buf, size);
    record->push_back(c_buf);
}

Now after usage, I wish to free the memory allocated. Would it go away on it's own? Or would I have to free() every element? I tried to call free like this:

for (int i =0; i < 100; i++) {
   free(record.at(i));
}

But it complains about const char.

    " error: no matching function for call to 'free'
    free(record.at(i));"  

I then used a cast:

  for (int i =0; i < 100; i++) {
      free((char *) record.at(i));
  }

Now it seems to run, but I'm not sure if it works? Does that look right?

[EDIT]
As per comments and answer below. Casting it is ok. An alternative is to use delete() as per: Unable to free const pointers in C (C's free has an issue, which was fixed in delete() in c++).

Community
  • 1
  • 1
Leo Ufimtsev
  • 6,240
  • 5
  • 40
  • 48

1 Answers1

1

What you're doing (I'm pretty sure) is technically allowed. However, it really makes no sense to malloc a const char*, as you wouldn't be able to initialize the memory after allocation without a cast.

free takes a void*, which is why the compiler complains when you pass it a const char*. const pointers are not implicitly convertible to void*. When you cast away the constness using (char*), you make it convertible, and free can take the variable.

To answer your question, yes, you do need to free each element before the vector is destroyed. It won't happen on it's own.

Truth be told, the code your professor is giving you is complete nonsense. If you're talking about binary data, perhaps you should be using std::vector<std::vector<std::uint8_t>> rather than vector<const char*>. If you're really holding strings, std::vector<std::string> makes more sense. This way, the memory is automatically free'd for you, because the container's destructors take care of it.

Collin
  • 11,977
  • 2
  • 46
  • 60