Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to avoid memory leaks when releasing unique_ptr from C++ to C

I have a C program that calls a C++ wrapper around a large C++ library. One of the functions of the C++ library is to provide some predictions, and those predictions will be used within C. I’m wondering where I should free or delete the memory. Here is some example code.

cpp_wrapper.cpp

#include "cpp_wrapper.h"


uint8_t * run_model(struct_with_model model_struct, const double * input_data) {
  // the model_struct is new'd in C++ in an earlier method

  // I have a method to convert the input data to std::vector for use in C++ code
  std::vector<double> data = get_data(input_data); 

  model_struct->model->LoadData(data);

  model_struct->model->run();

  std::vector<uint8_t> predictions = model_struct->model->GetPredictions();

  std::unique_ptr<uint8_t[]> classValues (new uint8_t[predictions.size()]);

  memcpy(classValues.get(), predictions.data(), sizeof(uint8_t) * predictions.size());

  model_struct->model->ClearData(); //clears data from model for future runs, if necessary

  return classValues.release()
}

void model_delete(model_struct) {
  // method to delete the model_struct when necessary
  delete model_struct;
}

I have a cpp_wrapper.h header file that declares these functions and calls extern C as necessary. On the C side, c_code.c:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

#include "cpp_wrapper.h"


/*
   There's a bunch of code here for ingesting data, initializing the model_struct, etc
*/

uint8_t * predictions = run_model(model_struct, input_data);

// Do stuff with predictions, as necessary

model_delete(model_struct);

free(predictions); // HERE is the question

I new the initial variable classValues in the C++ code, however I release the std::unique_ptr as the return of the C++ run_model function. My understanding was that when I release the memory to C, that the C code was responsible for freeing the memory. Is this the case? Should I have a C++ method to delete the predictions variable (from C), much like I have a C++ method to delete the model_struct variable? I’m confused about how to best manage the memory here. I was advised to not use malloc (or calloc) in C++, but since I’m passing the values back to C, maybe this is a better option…? I’m not sure.

>Solution :

The simplest solution is to divide the C++ call into two calls. The first one determines how big the needed buffer is. Then the memory can be allocated in the C part. In the second call the data is copied into this buffer. This way the memory management remains completely in the C part.

Alternatively, the C++ interface must provide a function to clear the memory. The C code calls this when the memory is to be released. The usual rule applies:

  • malloc -> free
  • new -> delete
  • new[] -> delete[]

If I see this correctly, you are implementing the second approach at the moment, but are incorrectly using new[] -> delete!

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading