循环中的自由strdup输出

时间:2017-11-30 16:15:17

标签: c++ strdup

我有一个循环试图从qml列表对象中读取数据,这是我的循环

char * argvarry[(gcps.size() * 5) + 8];
argvarry[0] = "-of";
argvarry[1] = "GTiff";
argvarry[2] = "-a_nodata";
argvarry[3] = "'0 0 0'";
argvarry[4] = "-a_srs";
argvarry[5] = a_srs;

int argc = 6;

for (int i = 0;i < gcps.size(); i++) {
    argvarry[argc] = "-gcp";argc++;//gcp_values
    gcppoint_ *a = qobject_cast<gcppoint_ *>(gcps.at(i).value<QObject *>());

      argvarry[argc]= strdup( const_cast<char*>(QString::number(a->row()).toStdString().c_str())); argc++;
      argvarry[argc] = strdup(const_cast<char*>(QString::number(a->column()).toStdString().c_str())); argc++;
      argvarry[argc] = strdup(const_cast<char*>(QString::number(a->lon()).toStdString().c_str())); argc++;
      argvarry[argc] =strdup( const_cast<char*>(QString::number(a->lat()).toStdString().c_str())); argc++;
}

我尝试了一些方法使上面的代码工作但没有工作, 例如,如果我使用strdup它将工作,但它需要被释放,我试图在变量中保存strdup的输出,然后在循环中释放它,但它释放所有变量。这是我的尝试

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

      char* srcX =strdup(const_cast<char*>(QString::number(a->row()).toStdString().c_str()));
      char* srcY = strdup(const_cast<char*>(QString::number(a->column()).toStdString().c_str()));
      char* dstX =strdup( const_cast<char*>(QString::number(a->lon()).toStdString().c_str()));
      char* dstY = strdup(const_cast<char*>(QString::number(a->lat()).toStdString().c_str()));
      qDebug() <<srcX<<" " <<srcY << " " <<dstX<< " " <<dstY;
     argvarry[i]=srcX;

      if(srcX)
          free(srcX) //does not work it frees argvarry[i] too

}
//...do some thing with argvarry
free????

我注意到所有argvarry[i]也将被释放,所以我不能再使用它们了。那我怎么能让它发挥作用,我太自由strdup但我无法处理它。如何更改此循环以及何时使用argvarry我免费strup结果?

如果我将上面的代码更改为类似的

char * srcX;
char * srcY;
char * dstX;
char * dstY;

for (int i = 0;i < gcps.size(); i++) {
    argvarry[argc] = "-gcp";argc++;//gcp_values
    gcppoint_ *a = qobject_cast<gcppoint_ *>(gcps.at(i).value<QObject *>());

      srcX= strdup( const_cast<char*>(QString::number(a->row()).toStdString().c_str())); 
      srcY = strdup(const_cast<char*>(QString::number(a->column()).toStdString().c_str())); 
      dstX = strdup(const_cast<char*>(QString::number(a->lon()).toStdString().c_str())); 
      dstY =strdup( const_cast<char*>(QString::number(a->lat()).toStdString().c_str()));
      argvarry[argc]=srcX;argc++;
      argvarry[argc]=srcY;argc++;
      argvarry[argc]=dstX;argc++;
      argvarry[argc]=dstY;argc++;
      }
          ///do things

         //free(srcX);free(srcY)

1 个答案:

答案 0 :(得分:1)

  char* srcX = const_cast<char*>(QString::number(a->row()).toStdString().c_str());

上面的问题是toStdString()返回一个临时的QString对象,由于QString对象是临时的,它会在行尾被销毁。这意味着当你稍后尝试使用它时,srcX是一个悬空指针。

如果你绝对需要一个char *指针数组,你需要确保它们指向的数据在数组的生命周期内保持有效。 strdup()是这样做的一种方法,但正如你所指出的那样,它有其自身的困难,特别是你需要在完成它们之后手动调用字符串上的free(),或者你将会泄漏记忆。

另一种方法是首先建立一个std :: string对象列表,如下所示:

// Build up a list of std::strings
std::vector<std::string> strsList;
strsList.push_back("-of");
strsList.push_back("GTiff");
strsList.push_back("-a_nodata");
strsList.push_back("'0 0 0'");
strsList.push_back("-a_srs");
strsList.push_back("a_srs");
for (int i = 0;i < gcps.size(); i++) {
   strsList.push_back("-gcp");
   strsList.push_back(QString::number(a->row()).toStdString());
   strsList.push_back(QString::number(a->column()).toStdString());
   strsList.push_back(QString::number(a->lon()).toStdString());
   strsList.push_back(QString::number(a->lat()).toStdString());
}

// Now create an array of pointers to the data in those std::strings
// This array will remain valid for as long as strsList remains valid and unmodified
char * argvarray[strsList.size()];
for (size_t i=0; i<strsList.size(); i++) argvarray[i] = const_cast<char *>(strsList[i].c_str());