Hi All, I have a bunch of code written with asprintf() and other functions that use the parameter list that contain one or many (char **)s to return newly allocated strings.
I want to use LCLint to help me check for memory leaks in the calling function. I have been racking my head trying to figure out how to do this but I have been going in circles. I used /*@only@*/ to try marking the memory, with no success, and /*@out@*/ to handle the cases where a NULL has been returned, this works. I have tried even using /*@only@*/ on the inner storage that I care about in my header file (which did not work): typedef /*@only@*/ char *myChar; int /*@alt void@*/ asprintf(/*@out@*/ myChar *cppOutBuffer, char* cpFormat, ...); I have included a version of asprintf.c and asprintf.h along with the calling function that I am using to try to get a memory leak detected error. If you run lclint on the asprintf_lclint_test code with -D_USE_MALL it produces the result I want to see (memory leak detected). Currently as the code stands (without the define switch) it does not yield any allocation error and everytime I introduce the /*@only@*/ tag I have more error that I do not understand how to resolve. The only way I can see to resolve this problem is to rewrite the functions to return only the allocated memory as the return value. This would be a lot of work. LCLint should be able to handle memory allocations returned in the parameter list, right? Any help would be great. Thanks, Andy King
#include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <string.h> #include "asprintf.h" int asprintf(char **cppOutBuffer, char *cpFormat, ...) { int iMaxLen = -9; int iRet = -9; FILE *fpNULLDev = NULL; va_list varArgList; va_start (varArgList, cpFormat); // Figure out how big the buffer needs to be. //iMaxLen = vsnprintf(NULL, 0, cpFormat, varArgList); fpNULLDev = fopen("/dev/null", "w"); if (fpNULLDev == NULL) { return -1; } iMaxLen = vfprintf(fpNULLDev, cpFormat, varArgList); if (iMaxLen > 0) { //Reserve enough space in the buffer for the formatted string //including the null terminator. *cppOutBuffer = malloc(iMaxLen + 1); if (*cppOutBuffer == NULL) { return (-1); } iRet = vsprintf(*cppOutBuffer, cpFormat, varArgList); if (iRet == -1) { return (-1); } } va_end(varArgList); return iMaxLen; }
#ifndef __ASPRINTF_H_ #define __ASPRINTF_H_ /*@printflike@*/ int /*@alt void@*/ asprintf(/*@out@*/ char **cppOutBuffer, char* cpFormat, ...); #endif
#include <stdio.h> #include <stdlib.h> #ifndef _USE_MALL #include "asprintf.h" #endif int main() { char *cpMyStr = NULL; #ifdef _USE_MALL cpMyStr = malloc(20); #else asprintf(&cpMyStr, "Hope this memory is marked as allocated under lclint?"); #endif if (cpMyStr == NULL) { return(-1); } //free(cpMyStr); return(0); }