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);
}

Reply via email to