Why does this function cause an assertion failure? 
Author Message
 Why does this function cause an assertion failure?

The function below causes an assertion failure on the marked line.  My
VC++ reports line 41 in fgetc.c "stream != NULL" is where the problem
happens supposedly.  Does anyone know how I could fix this?

static char *get_string(FILE * data,int length, int* buffer)
{
        char *temp, *temp2;  //local string pointers
        int i;                                  //temp counter
        temp = (char*)malloc(length);  //get memory for new string
        temp2 = temp;

        //get chars from file and add them to return string

        for (i = 0; i<length;i++)
        {
                if(!*buffer)
                {
Program fails here--->       (*temp2)=(char)fgetc(data);
                        if((*temp2)==EOF)
                        {
                                *buffer=true;

                        }
                }
                else

                temp2++;}
        temp2++;
        *temp2='\0';
        return(temp);

Quote:
}

Jon Robinson


Sat, 01 Oct 2005 18:51:14 GMT  
 Why does this function cause an assertion failure?

Quote:

> The function below causes an assertion failure on the marked line.

It shouldn't, really, because you didn't put an assert() call on that
line. Trust M$ to compile their libraries with debugging options on...
still, it makes this error quite obvious.

Quote:
> My VC++ reports line 41 in fgetc.c "stream != NULL" is where the problem
> happens supposedly.  Does anyone know how I could fix this?

Pass fgetc() a file pointer that isn't null, perhaps? But there's more:

Quote:
> static char *get_string(FILE * data,int length, int* buffer)
> {
>    char *temp, *temp2;  //local string pointers
>    int i;                                  //temp counter

Imprimis, those really aren't very useful comments. Everybody can tell
at a single glance that those are local string pointers; that shouldn't
need a comment. Comments should not be used to emphasize what is already
obvious, but to clarify what it unclear.

Quote:
>    temp = (char*)malloc(length);  //get memory for new string

Don't cast malloc(). It is unnecessary, obfuscates code, and reduces the
warning value of real casts. If your compiler complains when you remove
the cast, you either have forgotten to #include <stdio.h> (so do that),
or you're compiling C as if it were C++ (so don't do that, then).

Quote:
>    temp2 = temp;

>    //get chars from file and add them to return string

>    for (i = 0; i<length;i++)
>    {
>            if(!*buffer)

You do realise that if you call get_string with a non-zero third
argument, you never read any input at all? Is this specified in the
interface comments?

Quote:
>            {
> Program fails here--->  (*temp2)=(char)fgetc(data);

There are several things wrong here.
First of all, you do not need the parens around *temp2 at all, and
they're not making your code clearer. The unary * operator has a very
high precendence, or more strictly speaking, binds very closely. Lose
the parens, here as well as below.
Second, you are, judging from the error message, passing a null pointer
to get_string(), which get_string() merrily passes on to fgetc(), which
barfs on it. It might be wise to check that you call get_string()
correctly; it might be even wiser for get_string() to check that it is
called correctly, depending on who could call it.
Thirdly, fgetc() does not return an int for nothing. There is not enough
room in a char for both all possible char values _and_ EOF. Even in the
most benign of circumstances, casting that int to a char either (if char
is unsigned by default) casts EOF into an unsigned position, or (if char
is signed) casts another char into EOF's position as well, so...

Quote:
>                    if((*temp2)==EOF)

...either this comparison never succeeds because you're comparing a
shifted-to-positive ex-EOF to the negative true EOF, _or_ it succeeds
both for EOF and for another character value, most often 0xFF. And
remember, that's in the best circumstances - in principle, things could
be worse on your system.

Quote:
>                    {
>                            *buffer=true;

>                    }
>            }
>            else

>            temp2++;}

This indentation could be clearer, btw.

Quote:
>    temp2++;
>    *temp2='\0';

You have only asked for storage for length characters; you store length
characters in the loop _plus_ one terminating null character here.
Either ask for more memory or store one character less.

Quote:
>    return(temp);

You do not need the parens, but they don't do much harm here.

Quote:
> }

Richard


Sat, 01 Oct 2005 19:33:17 GMT  
 Why does this function cause an assertion failure?

Quote:

>> The function below causes an assertion failure on the marked line.
> It shouldn't, really, because you didn't put an assert() call on that
> line. Trust M$ to compile their libraries with debugging options on...
> still, it makes this error quite obvious.
>> My VC++ reports line 41 in fgetc.c "stream != NULL" is where the problem
>> happens supposedly.  Does anyone know how I could fix this?
> Pass fgetc() a file pointer that isn't null, perhaps? But there's more:
>> static char *get_string(FILE * data,int length, int* buffer)
>> {
>>        char *temp, *temp2;  //local string pointers
>>        int i;                                  //temp counter
> Imprimis, those really aren't very useful comments. Everybody can tell
> at a single glance that those are local string pointers; that shouldn't
> need a comment. Comments should not be used to emphasize what is already
> obvious, but to clarify what it unclear.
>>        temp = (char*)malloc(length);  //get memory for new string
> Don't cast malloc(). It is unnecessary, obfuscates code, and reduces the
> warning value of real casts. If your compiler complains when you remove
> the cast, you either have forgotten to #include <stdio.h> (so do that),
> or you're compiling C as if it were C++ (so don't do that, then).
>>        temp2 = temp;

>>        //get chars from file and add them to return string

>>        for (i = 0; i<length;i++)
>>        {
>>                if(!*buffer)
> You do realise that if you call get_string with a non-zero third
> argument, you never read any input at all? Is this specified in the
> interface comments?

Um, since when? The if statement above checks if *buffer is nonzero,
not if buffer is nonzero.
OTOH, if you do call get_string with a *zero* third argument, then
you get undefined behaviour.

--

| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #108 D+ ADA N+++|
| http://www.helsinki.fi/~palaste       W++ B OP+                     |
\----------------------------------------- Finland rules! ------------/
"And according to Occam's Toothbrush, we only need to optimise the most frequent
instructions."
   - Teemu Kerola



Sat, 01 Oct 2005 19:57:54 GMT  
 Why does this function cause an assertion failure?

Quote:
> The function below causes an assertion failure on the marked line.  My
> VC++ reports line 41 in fgetc.c "stream != NULL" is where the problem
> happens supposedly.  Does anyone know how I could fix this?

Is the stream pointed to by data opened before this function is
called? How do you make that sure?

Quote:
> static char *get_string(FILE * data,int length, int* buffer)
> {
>    char *temp, *temp2;  //local string pointers
>    int i;                                  //temp counter
>    temp = (char*)malloc(length);  //get memory for new string

For one, the cast of mallocs return value is unnecessary and can
hide failure to include stdlib.h. Please loose that cast.
Second, You need to check whether malloc was successful in
getting some memory for you. If not, you better don't write to
it.

Quote:
>    temp2 = temp;

>    //get chars from file and add them to return string

>    for (i = 0; i<length;i++)

That must be (i < length-1), as you store a '\0' to the buffer
after the loop.

Quote:
>    {
>            if(!*buffer)
>            {
> Program fails here--->  (*temp2)=(char)fgetc(data);

Again, the cast is unnecessary and even worse it can make you
loose the ability to check for EOF at all. You know char can be
signed or unsigned. That can be defined by the implementation.
So you better take a int variable check for EOF and if EOF isn't
returned you simply assign the value to your char buffer (temp2
in this case).

Quote:
>                    if((*temp2)==EOF)
>                    {
>                            *buffer=true;

Do you have a C99 compliant compiler? If not "true" is an
undefined identifier if you do not define it on your own or use
some system dependent extensions.

Quote:

>                    }
>            }
>            else

>            temp2++;}

Strange indention, that you use here.

Quote:
>    temp2++;
>    *temp2='\0';
>    return(temp);
> }

> Jon Robinson

This practice of allocating memory inside a function, but not
freeing it in there is disregarded by many programmers. Many
would require the calling function to supply this function with
enough memory to place the input in. Especially if the buffer is
not resized as needed. Sometimes it seems convenient to provide a
delete or destroy function for object created by the above.

I would rather go for:

--

"LISP  is worth learning for  the profound enlightenment  experience
you will have when you finally get it; that experience will make you
a better programmer for the rest of your days."   -- Eric S. Raymond



Sat, 01 Oct 2005 19:59:06 GMT  
 Why does this function cause an assertion failure?
Once upon a while "Zoran Cutura"
...

Quote:
> I would rather go for:

Ooops... I pressed the send button by accident!

I'ld rather go for:

static char *get_string(FILE *data, char *buf, int len)
{
  char *tmp = buf;

  while(tmp-buf < len-1) {
    int c = fgetc(data);

    if(c != EOF) tmp = c;

    tmp += 1;    
  }

  tmp = '\0';
  return buf;

Quote:
}

such that the calling function needs to provide both, the open
file-stream and the target buffer.

But than I could also be using fgets() instead. ;-)
--

"LISP  is worth learning for  the profound enlightenment  experience
you will have when you finally get it; that experience will make you
a better programmer for the rest of your days."   -- Eric S. Raymond



Sat, 01 Oct 2005 20:16:04 GMT  
 Why does this function cause an assertion failure?

Quote:


> >> static char *get_string(FILE * data,int length, int* buffer)
> >>           if(!*buffer)

> > You do realise that if you call get_string with a non-zero third
> > argument, you never read any input at all? Is this specified in the
> > interface comments?

> Um, since when? The if statement above checks if *buffer is nonzero,
> not if buffer is nonzero.

Er, yeah, that's what I meant. With a third argument that points to a
non-zero integer.

Richard



Sat, 01 Oct 2005 21:02:14 GMT  
 Why does this function cause an assertion failure?

Quote:


> >       temp = (char*)malloc(length);  //get memory for new string
> >       return(temp);

> This practice of allocating memory inside a function, but not
> freeing it in there is disregarded by many programmers.

I suppose you mean ill regarded or something similar. "Disregarded"
means "ignored".
In any case, this is not quite true. For some functions, it is simply
the best solution. Of course, it does require that this behaviour is
well documented, so that the user of this function will not forget to
free() the allocated memory.

Richard



Sat, 01 Oct 2005 21:06:22 GMT  
 Why does this function cause an assertion failure?

Quote:


>> >   temp = (char*)malloc(length);  //get memory for new string

>> >   return(temp);

>> This practice of allocating memory inside a function, but not
>> freeing it in there is disregarded by many programmers.

> I suppose you mean ill regarded or something similar. "Disregarded"
> means "ignored".

Yes, you are right. Sorry for my bad wording.

Quote:
> In any case, this is not quite true. For some functions, it is simply
> the best solution. Of course, it does require that this behaviour is
> well documented, so that the user of this function will not forget to
> free() the allocated memory.

In such a case I usually provide a destroy function that should
be called when the object is not needed any more, but I thought I
said this before.

--

"LISP  is worth learning for  the profound enlightenment  experience
you will have when you finally get it; that experience will make you
a better programmer for the rest of your days."   -- Eric S. Raymond



Sat, 01 Oct 2005 21:38:50 GMT  
 Why does this function cause an assertion failure?

Quote:


> > In any case, this is not quite true. For some functions, it is simply
> > the best solution. Of course, it does require that this behaviour is
> > well documented, so that the user of this function will not forget to
> > free() the allocated memory.

> In such a case I usually provide a destroy function that should
> be called when the object is not needed any more, but I thought I
> said this before.

That, of course, is a very good solution, but even in that case it
should be made clear that the destroy function does need to be called.

Richard



Sat, 01 Oct 2005 22:14:08 GMT  
 Why does this function cause an assertion failure?

Quote:
>This practice of allocating memory inside a function, but not
>freeing it in there is disregarded by many programmers.

Then, how do you explain the popularity of the Unix strdup() function?

Dan
--
Dan Pop
DESY Zeuthen, RZ group



Sat, 01 Oct 2005 22:06:02 GMT  
 Why does this function cause an assertion failure?

Quote:

>>This practice of allocating memory inside a function, but not
>>freeing it in there is disregarded by many programmers.

> Then, how do you explain the popularity of the Unix strdup() function?

There is to many popular things that aren't considered good at
all. ;-) But the relation between popularity and the term "many
programmers" is a bit unclear to me. Many need not be anywhere
near all or most.
--

"LISP  is worth learning for  the profound enlightenment  experience
you will have when you finally get it; that experience will make you
a better programmer for the rest of your days."   -- Eric S. Raymond


Sat, 01 Oct 2005 23:14:56 GMT  
 Why does this function cause an assertion failure?

Quote:


>>>This practice of allocating memory inside a function, but not
>>>freeing it in there is disregarded by many programmers.

>> Then, how do you explain the popularity of the Unix strdup() function?

>There is to many popular things that aren't considered good at
>all. ;-) But the relation between popularity and the term "many
>programmers" is a bit unclear to me. Many need not be anywhere
>near all or most.

Then, your original statement is devoid of any practical meaning.
You'll find "many" (in your sense of the word) programmers disliking
*any* programming practice.

Dan
--
Dan Pop
DESY Zeuthen, RZ group



Sun, 02 Oct 2005 00:26:12 GMT  
 
 [ 12 post ] 

 Relevant Pages 

1. delete operator causing assertion failure

2. Accessing ComboBox in dialog box causes an Assertion failure

3. These codes cause a assertion failure..

4. CAsyncSocket::Create() in thread causes assertion failure

5. CRecortset::Delete causes assertion failure!

6. MFC Callback Causes Assertion Failure

7. UpdateData(FALSE) causes assertion failure

8. Tooltips cause a assertion failure in regular dll

9. Tooltips used in dll cause assertion failure

10. CSocket in Dll causes an assertion failure

11. Multiple fonts cause assertion failure

12. Why is this function causing a memory leak?

 

 
Powered by phpBB® Forum Software