理解できないように見える別のvalgrindエラーがあります。スクリプトをロードし、 strtok() を使用して、バッファにロードされたスクリプト内のデータをトークン化するコードがあります。以下を使用して、バッファーのヒープにメモリを割り当てます。
char *pPngStr = new char[4096];
次に、関数の最後で、次を使用してメモリを解放します。
delete[] pPngStr;
Valgrind は割り当てを次のように報告します。
173 bytes in 1 blocks are definitely lost in loss record 3,753 of 4,627
Valgrind は、メモリを解放する行も次のように報告します。
Invalid free() / delete / delete[] / realloc()
これはすべて同じ関数内にあり、変数はクラスではなくその関数に対してのみローカルです。これがメモリ リークであると valgrind がどのように考えているのか、私は途方に暮れています。必要なすべてのメモリを割り当て、完了したら解放します。問題が何であるかわかりません。
完全な関数は次のとおりです (少し面倒かもしれません)。
void CSprite::LoadSprite()
{
FILE *pF = fopen("Data/Art/coin/coin.sprite", "rb");
if(!pF)
{
return;
}
fseek(pF, 0, SEEK_END);
int length = ftell(pF);
fseek(pF, 0, SEEK_SET);
char *aData = new char[length];
fread(aData, 1, length, pF);
CheckGLError();
/**
* The scripts are setup like so:
***********************************************
* Pngs:
* 4; // This is the number of frames.
* <pngname>_001.png;
* <pngname>_002.png;
* <pngname>_003.png;
* <pngname>_004.png;
*
* Properties:
* name=<obj name>;
* width=###;
* height=###;
* framerate=0.### // rate in seconds
************************************************
*/
mpSprite = new SGfxSprite;
char *pPngStr = new char[4096];
pPngStr = strtok(aData, "\n");
pPngStr = strtok(NULL, "\n");
int iNumFrames = atoi(pPngStr);
mpSprite->numFrames = iNumFrames;
mpSprite->textures = new GLuint[iNumFrames];
glGenTextures(iNumFrames, mpSprite->textures);
int i = 0; // used for loop only!
while(pPngStr != NULL)
{
pPngStr = strtok(NULL, "\n");
if(!strcmp(pPngStr, "Properties:") || i >= iNumFrames)
{
break;
}
if(mpPng->LoadPng(pPngStr))
{
CheckGLError();
glBindTexture(GL_TEXTURE_2D, mpSprite->textures[i]);
CheckGLError();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
CheckGLError();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
CheckGLError();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
CheckGLError();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
CheckGLError();
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
CheckGLError();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mpPng->miWidth, mpPng->miHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, mpPng->mpData);
CheckGLError();
}
++i;
}
pPngStr = strtok(NULL, "=\n");
pPngStr = strtok(NULL, "\n");
mpSprite->name = pPngStr;
pPngStr = strtok(NULL, "=\n");
pPngStr = strtok(NULL, "\n");
mpSprite->width = atoi(pPngStr);
pPngStr = strtok(NULL, "=\n");
pPngStr = strtok(NULL, "\n");
mpSprite->height = atoi(pPngStr);
pPngStr = strtok(NULL, "=\n");
pPngStr = strtok(NULL, "\n");
mpSprite->framerate = (atof(pPngStr) * 1000);
mpSprite->x = 0;
mpSprite->y = 0;
mpSprite->currentFrame = 0;
mpSprite->paintTimer = 0;
fclose(pF);
delete[] pPngStr, aData;
}
*注意: この関数には OpenGL コードが含まれており、ここで定義されていないデータ構造からメンバーを呼び出します。このコードは、Qt Creator 2.4.1 を使用して g++ (gcc 4.6) を使用する Xubuntu 12.04 でも警告やエラーなしでコンパイルされます。