[英]Valgrind check for memory leak in C
我們在C中編寫了一套代碼,它將dir中的Matlab數據文件(.mat)作為輸入,它還調用GSL函數來搜索多項式的根,並生成隨機數。 我們正在研究OSX。 我們使用Valgrind
檢查是否有任何內存泄漏,因為我們在代碼中使用了大量的malloc
和free
。 它確實幫助我們在很多地方找到了內存泄漏。 但是,還有一個我們無法解決的問題。 函數listfileswext
存在問題(它在名為maxphaseutils.c
的子例程中列出具有給定擴展名的目錄中的所有文件,即.mat
):
char ** listfileswext (const char *ext, const char *dirName, size_t *nFiles, size_t *maxFileNameLen)
{
/*printf("------- %s -------\n",ext);
printf("Extension string length %zu\n",strlen(ext));*/
char *pattern = (char *)malloc((3+strlen(ext))*sizeof(char));
DIR *dp;
struct dirent *ep;
char **fileList;
size_t lpc;
pattern[0] = '*';
pattern[1] = '.';
pattern[2] = '\0';
strcat(pattern,ext);
/*printf("Pattern %s\n",pattern);*/
/* Step 1: Count the number of files with the required
extension.
*/
size_t countValidFiles = 0;
dp = opendir(dirName);
if (dp != NULL){
while ((ep = readdir(dp))){
/*printf("Checking file %s\n",ep->d_name);*/
if(!fnmatch(pattern, ep->d_name, (FNM_FILE_NAME|FNM_PERIOD))){
/* Match. Increment counter */
/*printf("found match with pattern %s\n",pattern);*/
countValidFiles++;
}
}
(void) closedir (dp);
/*
Apparently, there is no need to free ep as it is declared to be 'static' in the readdir function
*/
}
else{
printf ("Couldn't open the directory %s\n",dirName);
free(pattern);
return NULL;
}
*nFiles = countValidFiles;
/* Step 2: Create storage for list of filenames */
fileList = (char **)malloc(countValidFiles*sizeof(char *));
/* Can't find a better way than to repeat the whole loop again */
countValidFiles = 0;
dp = opendir(dirName);
if (dp != NULL){
while ((ep = readdir(dp))){
if(!fnmatch(pattern, ep->d_name, (FNM_FILE_NAME|FNM_PERIOD))){
fileList[countValidFiles] = (char *)malloc(strlen(ep->d_name)*sizeof(char));
strcpy(fileList[countValidFiles],ep->d_name);
/* Match. Increment counter */
countValidFiles++;
}
}
(void) closedir (dp);
}
else{
printf ("Couldn't open the directory %s\n",dirName);
return NULL;
}
/*Find longest filename */
size_t fileNameLen;
*maxFileNameLen = 0;
size_t lpc1;
for (lpc1 = 0; lpc1 < *nFiles; lpc1++){
fileNameLen = strlen(fileList[lpc1]);
if ( fileNameLen > *maxFileNameLen)
*maxFileNameLen = fileNameLen;
}
/* Wrap up */
free(pattern);
return fileList;
}
在此函數中,調用變量fileList
char **inputFileList;
size_t nInputFiles, maxFileNameLen;
inputFileList = listfileswext("mat", simDataDir, &nInputFiles, &maxFileNameLen);
然后釋放
for(lpc1 = 0; lpc1 < nInputFiles; lpc1++){
/* Free up dynamically allocated memory for file list*/
free(inputFileList[lpc1]);
}
/* Free up dynamically allocated memory */
free(inputFileList);
在主要功能如上所示。 正如您所看到的, fileList
在main中被釋放為inputFileList
而不是在已分配的函數( listfileswext
)中。 我們認為沒關系。 運行Valgrind
,它顯示
==8643== Invalid write of size 8
==8643== at 0x101921031: _platform_memmove$VARIANT$Unknown (in /usr/lib/system/libsystem_platform.dylib)
==8643== by 0x1016E33AD: stpcpy (in /usr/lib/system/libsystem_c.dylib)
==8643== by 0x101755F96: __strcpy_chk (in /usr/lib/system/libsystem_c.dylib)
==8643== by 0x1000044B2: listfileswext (maxphaseutils.c:153)
==8643== by 0x100005FBD: main (perfeval_snglproc.c:41)
==8643== Address 0x104c6381d is 13 bytes inside a block of size 20 alloc'd
==8643== at 0x100010EBB: malloc (vg_replace_malloc.c:303)
==8643== by 0x10000447C: listfileswext (maxphaseutils.c:152)
==8643== by 0x100005FBD: main (c:41)
和
==8643== Invalid read of size 8
==8643== at 0x101921040: _platform_memmove$VARIANT$Unknown (in /usr/lib/system/libsystem_platform.dylib)
==8643== by 0x101756127: __strcat_chk (in /usr/lib/system/libsystem_c.dylib)
==8643== by 0x1000060CE: main (perfeval_snglproc.c:67)
==8643== Address 0x104c63224 is 4 bytes inside a block of size 11 alloc'd
==8643== at 0x100010EBB: malloc (vg_replace_malloc.c:303)
==8643== by 0x10000447C: listfileswext (maxphaseutils.c:152)
==8643== by 0x100005FBD: main (perfeval_snglproc.c:41)
這里perfeval_snglproc.c
是主要的。 此外,還有一大堆員工如下所示,這與我們制作的功能無關(我們可能無法控制這些系統文件):
==8643== 168 bytes in 7 blocks are possibly lost in loss record 657 of 1,081
==8643== at 0x10001178B: malloc_zone_calloc (vg_replace_malloc.c:717)
==8643== by 0x1019C737C: NXHashInsert (in /usr/lib/libobjc.A.dylib)
==8643== by 0x1019C746F: _NXHashRehashToCapacity (in /usr/lib/libobjc.A.dylib)
==8643== by 0x1019C73B9: NXHashInsert (in /usr/lib/libobjc.A.dylib)
==8643== by 0x1019D6687: realizeClass(objc_class*) (in /usr/lib/libobjc.A.dylib)
==8643== by 0x1019D5B53: realizeClass(objc_class*) (in /usr/lib/libobjc.A.dylib)
==8643== by 0x1019CA38D: look_up_class (in /usr/lib/libobjc.A.dylib)
==8643== by 0x1019CA1B9: objc_getFutureClass (in /usr/lib/libobjc.A.dylib)
==8643== by 0x101D51D3F: __CFInitialize (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
==8643== by 0x7FFF5FC12BC7: ImageLoaderMachO::doImageInit(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==8643== by 0x7FFF5FC12E8C: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==8643== by 0x7FFF5FC0F890: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==8643==
==8643== 168 (32 direct, 136 indirect) bytes in 1 blocks are definitely lost in loss record 658 of 1,081
==8643== at 0x10001117C: malloc_zone_malloc (vg_replace_malloc.c:305)
==8643== by 0x101D6FF79: CFUniCharGetUnicodePropertyDataForPlane (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
==8643== by 0x101D6FEBE: CFUniCharGetNumberOfPlanesForUnicodePropertyData (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
==8643== by 0x101D6F9A3: __CFUniCharLoadDecompositionTable (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
==8643== by 0x101D6F048: CFUniCharDecompose (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
==8643== by 0x101D681CE: CFStringGetFileSystemRepresentation (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
==8643== by 0x101E91929: _CFURLCreateWithFileSystemPath (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
==8643== by 0x101D693D9: _CFBundleCopyBundleURLForExecutableURL (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
==8643== by 0x101D63DE4: _CFBundleGetMainBundleAlreadyLocked (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
==8643== by 0x101D63D5A: CFBundleGetMainBundle (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
==8643== by 0x101D8C0A7: _CFPrefsGetCacheStringForBundleID (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
==8643== by 0x101EDADC8: __50+[CFPrefsSearchListSource withSnapshotSearchList:]_block_invoke (in /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation)
請幫忙! 提前致謝!
根據此 ,泄漏不會被你的程序造成的,而是由系統庫。
對於錯誤,在為c-string分配空間時,需要為尾隨零創建空間,因此要進行更改
fileList[countValidFiles] = (char *)malloc(strlen(ep->d_name)*sizeof(char));
至
fileList[countValidFiles] = (char *)malloc((strlen(ep->d_name) + 1)*sizeof(char));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.