-1

I have a struct which contains a set of char* properties.

struct gcp_values {
char* srcX;
char* srcY;
char* dstX;
char* dstY;
};

well I fill it in a loop from a set of qt objects

std::vector<GeoRefLibrary::gcp_values> gcpvalues(vl.size());

    for(int i=0;i<vl.size();i++) {
        gcppoint_ *a = qobject_cast<gcppoint_ *>(vl.at(i).value<QObject *>());
        gcpvalues[i].srcX= strdup(QString::number(a->row()).toStdString().c_str());
        gcpvalues[i].srcY= strdup(QString::number(a->column()).toStdString().c_str());
        gcpvalues[i].dstX= strdup(QString::number(a->lon()).toStdString().c_str());
        gcpvalues[i].dstY= strdup(QString::number(a->lat()).toStdString().c_str());
    }

when I run valgrind test it results these outpt

12 bytes in 4 blocks are definitely lost in loss record 813 of 19,623
14 bytes in 4 blocks are definitely lost in loss record 889 of 19,623
16 bytes in 1 blocks are definitely lost in loss record 3,621 of 19,623
32 bytes in 4 blocks are definitely lost in loss record 8,851 of 19,623
36 bytes in 4 blocks are definitely lost in loss record 9,134 of 19,623

these errors are at those lines in loop. I tried to delete [] gcpvalues but it returned wrong delete/free error. I searched and found this post too

delete[] an array of objects

but cant find the solutions,can some one please help me with this problem?

I also tried

    struct gcp_values {
    QString srcX;
    QString  srcY;
   QString  dstX;
    QString  dstY;
};

and it returns the same errors


I changed the loop into this and it seems errors are gone

for(int i=0;i<vl.size();i++) {
    gcppoint_ *a = qobject_cast<gcppoint_ *>(vl.at(i).value<QObject *>());

      char* srcX = strdup(QString::number(a->row()).toStdString().c_str());
      char* srcY = strdup(QString::number(a->column()).toStdString().c_str());
      char* dstX = strdup(QString::number(a->lon()).toStdString().c_str());
      char* dstY = strdup(QString::number(a->lat()).toStdString().c_str());
      gcpvalues[i].srcX=srcX;
      gcpvalues[i].srcY= srcY;
      gcpvalues[i].dstX= dstX;
      gcpvalues[i].dstY= dstY;
    if(srcX) { free(srcX);}
    if(srcY) { free(srcY);}
    if(dstX) { free(dstX);}
    if(dstY) { free(dstY);}
}
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Majid Hojati
  • 1,740
  • 4
  • 29
  • 61
  • 1
    The `strdup` documentation specifically says: *The returned pointer must be passed to free to avoid a memory leak.* – Nico Schertler Nov 11 '17 at 09:57
  • 2
    This problem could be trivially avoided by just putting `QString`s in your `struct`. Manual memory management is difficult and unnecessary. Don't do it. – nwp Nov 11 '17 at 10:41
  • @nwp then later how can we convert Qstring to char* as I need a char* in later functions. – Majid Hojati Nov 11 '17 at 10:55
  • @NicoSchertler how can I use that? – Majid Hojati Nov 11 '17 at 10:55
  • Write a destructor for your struct that frees the char arrays. `delete[]` should work as well. – Nico Schertler Nov 11 '17 at 10:57
  • Same as you did now. `QString srcX; something_that_takes_char_pointer(srcX.toStdString().c_str());`. Just make sure `something_that_takes_char_pointer` doesn't do something stupid like calling `free` on that pointer. Although the better solution would be to change the function to take a string instead. – nwp Nov 11 '17 at 10:58
  • @nwp as I tried befor .c_str() returns const char* and it later I have to allocate memory to cnovert const char to char – Majid Hojati Nov 11 '17 at 11:01
  • @nwp as I tried also std::string srcX also returns the same error. does it make any changes if I use Qstring instead? – Majid Hojati Nov 11 '17 at 11:03
  • _I need a char* in later function_ why? Why don’t they use std::string? –  Nov 11 '17 at 11:05
  • @manni66 in fact it is a library which I am using (gdal) and it accepts char * as input. – Majid Hojati Nov 11 '17 at 11:08
  • 1
    With C++ 17 you can get a non const char* to the std::string data with data(). –  Nov 11 '17 at 11:08
  • The gdal C++ API uses const char*. Do you refer to an out parameter? –  Nov 11 '17 at 11:12
  • @manni66 but I need its opossite, as c_str() returns const char* and I need to have a char * – Majid Hojati Nov 11 '17 at 11:12
  • @manni66 yes, in this function GDALGeneralCmdLineProcessor it gets a char** as input of commandline – Majid Hojati Nov 11 '17 at 11:14

1 Answers1

1

strdup is a POSIX function, and POSIX functions which allocate memory (and do not provide type-specific deallocation functions such as fclose and freeaddrinfo) expect the caller to eventually call free to deallocate the allocated memory.

POSIX does not use C++ memory allocation, so operator delete[] is not correct here.

Florian Weimer
  • 32,022
  • 3
  • 48
  • 92