Hello all,

First let me say thank you for splint.  When I use it, I
feel like I
have an experienced and meticulous C coder looking over
my shoulder.
Lately, I've tried something a little more ambitious, and
either
I don't understand what is wrong with my code or I'm
failing to
annotate it properly, so I'm coming to you for help. 
I've made
a small example to show what approach I'm using and what
messages
splint is generating.  Essentially I want to malloc
memory for
a structure and a string component of the structure, use
it, and
later free all the memory.  Optionally, I want to be able
to use
a non-dynamically allocated structure and string.  I'm
including
below the .splintrc file, widget.h, widget.c, and the splint 
messages.  I'd be very grateful to anyone who can help me
understand
what I need to do here.  Thanks.  -Dan Good


__.splintrc_________________________________________________

-unrecog
#-mustfreefresh
#-usereleased
-compdef
#-mustfreeonly
#-compmempass
-exportlocal


__widget.h__________________________________________________

#ifndef _WIDGET_H
#define _WIDGET_H 1

#define WIDGET_MALLOCED 1

struct widget {
    /*@only@*/     char   *name;
    unsigned int flags;
};
typedef /*@abstract@*/ struct widget widget;

/*@null@*/ /*@only@*/ widget *widgetNew(const size_t size);

/*@null@*/ widget *widgetInit(/*@null@*/ /*@partial@*/
/*@only@*/ widget *x, /*@null@*/ /*@only@*/ const char
*str, const unsigned int initialize);

void widgetFree(/*@null@*/ /*@only@*/ widget *x);

/*@null@*/ extern inline char *widgetName(/*@null@*/
widget *x) { return (x != NULL) ? x->name : NULL; }

#endif


__widget.c__________________________________________________

#include <stdlib.h>
#include <errno.h>
#include "widget.h"

widget *widgetNew(const size_t size) {
    /*@only@*/ char *str;
    widget *x;

    if (size < 1) { errno = EINVAL; return NULL; }
    str = (char *) malloc(size);
    if (str == NULL) return NULL; /* malloc sets errno */
    x = (widget *) malloc(sizeof(struct widget));
    if (x == NULL) return NULL; /* malloc sets errno */

    if (widgetInit(x,str,1) == NULL) return NULL;
    x->flags |= WIDGET_MALLOCED;
    return x;
}

widget *widgetInit(widget *x, const char *str, const
unsigned int initialize) {
    if (x == NULL)   { errno = EINVAL; return NULL; }
    if (str == NULL) { errno = EINVAL; return NULL; }
    x->name = (char *) str;
    if (initialize != 0) *x->name = '\0';
    x->flags = 0;
    return x;
}

void widgetFree(widget *x) {
    if (x != NULL && (x->flags & WIDGET_MALLOCED) != 0) {
        free(x->name);
        free(x);
    }
}

/*@null@*/ char *widgetName(/*@null@*/ widget *x) {
return (x != NULL) ? x->name : NULL; }


__splint widget.c___________________________________________

Splint 3.0.1.6 --- 19 Jul 2002

widget.h: (in function widgetName)
widget.h:18:103: Released storage x->name reachable from
parameter at return
                    point
  Memory is used after it has been released (either by
passing as an only param
  or assigning to an only global). (Use -usereleased to
inhibit warning)
   widget.h:18:74: Storage x->name is released
widget.c: (in function widgetNew)
widget.c:9:49: Only storage str not released before return
  A memory leak has been detected. Only-qualified storage
is not released
  before the last reference to it is lost. (Use
-mustfreeonly to inhibit
  warning)
   widget.c:6:22: Storage str becomes only
widget.c:13:32: Fresh storage str not released before return
  A memory leak has been detected. Storage allocated
locally is not released
  before the last reference to it is lost. (Use
-mustfreefresh to inhibit
  warning)
   widget.c:10:5: Fresh storage str allocated
widget.c: (in function widgetInit)
widget.c:21:52: Only storage str not released before return
   widget.c:20:43: Storage str becomes only
widget.c:22:52: Only storage x not released before return
   widget.c:20:28: Storage x becomes only
widget.c: (in function widgetName)
widget.c:36:89: Released storage x->name reachable from
parameter at return
                   point
   widget.c:36:60: Storage x->name is released

Finished checking --- 6 code warnings


Reply via email to