“潜在内存泄漏”警告

问题描述 投票:0回答:2

我创建了这段小代码来测试

copyMemZone
函数,它允许我从内存区域提取数据。
在下面的示例中,参数是手动输入的(用于测试),但此代码必须在更完整的程序中使用。

我不觉得我犯了错误,但 Qt 向我显示了以下消息:

“dataSource”[clang-analyzer-unix.Malloc] 指向的潜在内存泄漏

对于以下行:

unsigned char* dataDest = (unsigned char*)malloc(sizeMaxDest*sizeof(unsigned char));`  

此消息正常吗?
我的代码写错了吗?

int copyMemZone(unsigned char* zoneSourceFonc, size_t debutSourceFonc, size_t finSourceFonc, unsigned char** zoneDestFonc);
int copyMemZone(unsigned char *zoneSourceFonc, size_t debutSourceFonc, size_t finSourceFonc, unsigned char **zoneDestFonc)
{
  // Initialization
  int cursorMem = 0;

  if(finSourceFonc>debutSourceFonc)
  {
    // For each Character to Copy
    for (size_t i = debutSourceFonc; i < finSourceFonc; i++)
    {
      // Memorization
      (*zoneDestFonc)[cursorMem] = zoneSourceFonc[i];
      cursorMem++;
    }
  }

  return EXIT_SUCCESS;
}

int main()
{
  // Initialization
  int sizeSource  = 10;                     // Size of Source Memory
  int beginMemo   = 2;  int endMemo   = 8;  // Parameters to copy (to extract) caracters
  int sizeMaxDest = 10;                     // Size of Destination Memory


  // Memory Allocation
  unsigned char* dataSource = (unsigned char*)malloc(sizeSource*sizeof(unsigned char));
  if(dataSource==NULL) return EXIT_FAILURE;

  // Mémorisation
  dataSource[0] = '0';
  dataSource[1] = 'X';
  dataSource[2] = 'M';
  dataSource[3] = 'E';
  dataSource[4] = 'M';
  dataSource[5] = 'O';
  dataSource[6] = 'R';
  dataSource[7] = 'Y';
  dataSource[8] = '8';
  dataSource[9] = '7';


  // Memory Allocation
  unsigned char* dataDest = (unsigned char*)malloc(sizeMaxDest*sizeof(unsigned char));
  if(dataDest==NULL) return EXIT_FAILURE;
  int tailleDest          = endMemo-beginMemo;

  // Copying the Memory Area
  copyMemZone((unsigned char*)dataSource,beginMemo,endMemo,&dataDest);


  // Display after copying
  for(int i=0;i<tailleDest;i++) qDebug() << QChar(dataDest[i]);

  // Free Memory
  free(dataDest);
  free(dataSource);
}
c++ qt memory-leaks
2个回答
2
投票

如果

dataSource
malloc
失败,您不会释放
dataDest

另外,最好使用

nullptr
而不是
NULL

您应该将代码更改为以下内容:

if (dataDest == nullptr)
{
    free(dataSource);
    return EXIT_FAILURE;
}

此外,与其使用

malloc
/
new
动态分配内存,然后使用
free
/
delete
释放内存,也许最好使用
std::vector
,如下所示:

#include <vector>
#include <algorithm>

int main()
{
  int sizeSource  = 10;  // Size of Source Memory
  int beginMemo   = 2;   // Parameters to copy (to extract) characters 
  int endMemo     = 8;   // Parameters to copy (to extract) characters
  int sizeMaxDest = 10;  // Size of Destination Memory

  std::vector<unsigned char> dataSource{'0', 'X', 'M', 'E', 'M', 'O', 'R', 'Y', '8', '7'};

  std::vector<unsigned char> dataDest;
  dataDest.reserve(sizeMaxDest);
  std::copy(dataSource.begin() + beginMemo, dataSource.begin() + endMemo, std::back_inserter(dataDest));

  for (unsigned char c : dataDest)
  {
    qDebug() << QChar(c);
  }
}

2
投票

在现代 C++ 中,显式使用

malloc
/
free
new
/
delete
被认为是不好的做法。

参见:
C++ 核心指南

R.10:避免
malloc()
free()

原因

malloc()
free()
不支持构造和销毁,并且不能与
new
delete
很好地混合。

C++ 核心指南

R.11:避免明确调用
new
delete

原因

new
返回的指针应该属于资源句柄(可以调用
delete
)。如果
new
返回的指针被分配给普通/裸指针,则该对象可能会泄漏。

在你的情况下,你应该使用

std::vector<unsigned char>

int main()
{
  int sizeSource  = 10;
  int beginMemo   = 2;  
  int endMemo   = 8;
  int sizeMaxDest = 10;

  std::vector<unsigned char> dataSource{ '0', 'X', 'M', 'E', 'M', 'O', 'R', 'Y', '8', '7'};

  std::vector<unsigned char> dataDest;
  int tailleDest          = endMemo-beginMemo;

  dataDest =  { dataSource.begin() + beginMemo, dataSource.begin() + endMemo};


  for(auto x : tailleDest) qDebug() << QChar(x);
}

在 Qt 中,这条规则有例外。 Qt 有自己的内存管理模式,其中

QObject
是父子关系。然后,当设置了父级时,在 Qt 中显式使用
new
就可以了(不需要
delete
,因为父级负责释放对象)。

题外话: 如果注释只是重复已经说明的符号名称,请勿使用注释。这是毫无意义的。最常见的说法是显而易见的事情只是一种噪音。正如鲍勃叔叔所说:“注释是程序员在代码中直接表达其意图的失败”。因此,注释对于添加无法清楚地读取表单代码(符号名称)的信息很有用。

© www.soinside.com 2019 - 2024. All rights reserved.