fclose() after getline() function.

I

InuY4sha

I don't get the reason after using getline() on a FILE* I can't close
the file (I get a segfault).
I'mlooking at the function source and I see it calls getdelim()
function.. which doesn't seem to close the file... wondering why..
 
I

InuY4sha

     Neither do I, since you've shown no code and I have no idea
what getline() function you're talking about (there's no getline()
in the Standard library, so it must be something you got elsewhere).

     If you posted a short, complete program that demonstrates the
problem, and at the very least provided a pointer to the source of
this getline() function, maybe someone could help.  As it is ...


     It's customary at this point to say "You have an error on
line forty-two" or "The bank foreclosed on my crystal ball" or
"Please stop thinking in Hungarian; I'm having trouble reading
your mind," but what all of these mean is

     The Doctor Needs More Than "It Hurts" To Make A Diagnosis.


ehehe,
oK I'll give the whole storyline.. I picked up the first google
results (like this one:http://linux.die.net/man/3/getline) for "man
getline" and they show this "getline" function behaviour which is
always the same -and it works in my code-
Reading the manpage I erroneously thought such function was defined in
the stdlib.. and on the example too, they include stdio and stdlib
only.. the above define "_GNU_SOURCE" stands for something that I
*don't* know so I ignored it (while probably it's the key).
Anyway.. the code is this:

#define _GNU_SOURCE
#include <stdio.h> /*fopen*/
#include <stdlib.h>

long filelines(const char *filename){
FILE * fp;
char * line = NULL; size_t len = 0;
long lines = 0;
fp = fopen(filename, "r");
if (fp == NULL) return lines;
while (( getline(&line, &len, fp)) != -1) {
lines++;
}
if (line) free(line);
//fclose(fp); //[Argh here I crash ... BUT WHY?]
return lines;
}
 
K

Keith Thompson

Eric Sosman said:
[*] Well, "almost the same" and "almost all." It's possible
that the very last line of the file has no '\n' at the end, so the
line count could be one greater than the '\n' count. To handle
this case,
[...]

It depends on how you define "line". The "wc" command, for example,
counts newline characters. A file with no newline (including an empty
file) is reported to have 0 lines.

I'm not saying wc is right and you're wrong, just that you need to
define what you're counting.
 
F

Falcon Kirtaran

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Neither do I, since you've shown no code and I have no idea
what getline() function you're talking about (there's no getline()
in the Standard library, so it must be something you got elsewhere).

If you posted a short, complete program that demonstrates the
problem, and at the very least provided a pointer to the source of
this getline() function, maybe someone could help. As it is ...

It's customary at this point to say "You have an error on
line forty-two" or "The bank foreclosed on my crystal ball" or
"Please stop thinking in Hungarian; I'm having trouble reading
your mind," but what all of these mean is

The Doctor Needs More Than "It Hurts" To Make A Diagnosis.


ehehe,
oK I'll give the whole storyline.. I picked up the first google
results (like this one:http://linux.die.net/man/3/getline) for "man
getline" and they show this "getline" function behaviour which is
always the same -and it works in my code-
Reading the manpage I erroneously thought such function was defined in
the stdlib.. and on the example too, they include stdio and stdlib
only.. the above define "_GNU_SOURCE" stands for something that I
*don't* know so I ignored it (while probably it's the key).
Anyway.. the code is this:

#define _GNU_SOURCE
#include <stdio.h> /*fopen*/
#include <stdlib.h>

long filelines(const char *filename){
FILE * fp;
char * line = NULL; size_t len = 0;
long lines = 0;
fp = fopen(filename, "r");
if (fp == NULL) return lines;
while (( getline(&line, &len, fp)) != -1) {
lines++;
}
if (line) free(line);
//fclose(fp); //[Argh here I crash ... BUT WHY?]
return lines;
}

That code looks perfectly intact. In most buggy code I see, fclose()
segfaults because its argument is not a valid FILE*. Were I you, I
would run a memory debugger (such as valgrind; I assume you are using
linux) and investigate the backtrace to see where the segfault happens.

As a point of interest, you don't need to check that the argument to
free() is non-null. It simply does nothing if its argument is null.

- --
- --Falcon Darkstar Christopher Momot
- --
- --OpenPGP: (7902:4457) 9282:A431

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iQIcBAEBAgAGBQJKecP+AAoJEOGPymTbQp7G3CIP/iFsLLKbkl/YhOfPFaNOzzmQ
sZrXKs4xe+lbVpZBIPTK3+76aQ9X3NIT+tR5drlSU8IS5NeKWbDlObaC/ltkYnha
O7TUCVfgv3/ooCe7VggqzjILDtKeoyahhI3m9ozfvD8pMIJnGT/NLJ789Aka1ECX
ZzuMJeMQTL138ALFjPvgBfAtZ3G8M/aNr++J9PwwJBYJpWot2jkXApINu2j31Uaf
uboOJnBm0sXrucs8yQVGGz25L58vDLrN5ZkIQgSuYQoB+ybQCN2BUPlChLtQpRwU
LpEg5ekm5LWlqu9DDdL/jrtu9akDNXqXVKD3KmJlWewT6MKUuoKpbLQdoF82rXaX
MINi7/Lz0YSxeQ6JRUQl/52/JL5KVXLtdsVj5Cm2m4D3F/gn3HnIPRAoUjgKz2Xa
mWlfVJVErhKMnhOTQqzLcktAufIxanjsBlbwBp9H/FrTEYd10q6Z5LmEj8v5yN0y
bUdxF01PhkdSv8NGK0iPPI9lKkbSpMWEUUBuodtqQE+EJR0natH2vIlQwW4rcyjn
ueen71XOHKUUO2WI4eIOQZMKpUeR1vd3vikQntXlv5+ajehGZ/jJDBuXRottNQxj
OSMUPVyUAQ+KKvfhiIW8X7610gLF16JUKjBGLO28BwrpcXN/HQ/utibCC4RorNXz
ec1SKeJiK9m5dN78+zhP
=Ie3j
-----END PGP SIGNATURE-----
 
A

Antoninus Twink

Unfortunately, I still don't know. One possibility is that
the getline() your program uses is not the same getline() that
is described at the link you gave, and that it's doing something
unexpected to or with its arguments.

I think you may be right. The code looks 100% fine and dandy to me.

Try running
nm your_executable | grep getline
and check you're linking against the version in glibc.

Failing that, Falcon's advice to run your program through valgrind is a
good next move.
 
P

Phil Carmody

Keith Thompson said:
Eric Sosman said:
[*] Well, "almost the same" and "almost all." It's possible
that the very last line of the file has no '\n' at the end, so the
line count could be one greater than the '\n' count. To handle
this case,
[...]

It depends on how you define "line". The "wc" command, for example,
counts newline characters. A file with no newline (including an empty
file) is reported to have 0 lines.

I'm not saying wc is right and you're wrong, just that you need to
define what you're counting.

It seems to maintain this identity, which I can approve of:

wc ( cat (all files) ) = sum ( wc (each file) )

Phil
 
N

Nobody

oK I'll give the whole storyline.. I picked up the first google
results (like this one:http://linux.die.net/man/3/getline) for "man
getline" and they show this "getline" function behaviour which is
always the same -and it works in my code-
Reading the manpage I erroneously thought such function was defined in
the stdlib.. and on the example too, they include stdio and stdlib
only.. the above define "_GNU_SOURCE" stands for something that I
*don't* know so I ignored it (while probably it's the key).

Defining _GNU_SOURCE enables various GNU extensions which aren't part of
the ISO C standards. getline() is one such extension.
Anyway.. the code is this:
[snip]

//fclose(fp); //[Argh here I crash ... BUT WHY?]

There's nothing wrong with filelines().

The first possibility which springs to mind is that something else in your
program corrupted the heap (the region of memory used by malloc()) before
filelines() was called.

If something corrupts the heap, it tends to result in a subsequent call to
malloc() or free() crashing. Heap corruption isn't easy to debug with a
normal debugger (e.g. gdb). valgrind or electric fence may help, although
I'd start by looking for places where you might be overflowing a malloc()d
buffer.
 
I

InuY4sha

     But if all you're trying to do is count lines, you don't need
all this machinery anyhow.  

Unfortunately not.. what I want to do is a bit more complicated:
1) Count the N lines of a file
2) Generate a char **lines = malloc(sizeof(char*)*N);
3) Setting lines[x] = NULL and passing it to getlines
4) Parse it
5) Update the lines when necessary and store it back.

The nice thing here is that I have the file splitted in lines so it's
easier to handle it.

So that "getline" function, which malloc-ate the char arrays to the
correct size in my place and does everything *really* is a convenient
toy (imho).
The sample code I gave you was the smallest piece where I used it
(which takes care of point 1 in the above list of tasks.
 
I

InuY4sha

That code looks perfectly intact.  In most buggy code I see, fclose()
segfaults because its argument is not a valid FILE*.  Were I you, I
would run a memory debugger (such as valgrind; I assume you are using
linux) and investigate the backtrace to see where the segfault happens.

As a point of interest, you don't need to check that the argument to
free() is non-null.  It simply does nothing if its argument is null.

Nice to know (that code is just a copy&paste of the example provided
here http://linux.die.net/man/3/getline .The check comes from there).
- --
- --Falcon Darkstar Christopher Momot

Thanks for the advice! I'll try valgrind and let you know!
 
I

InuY4sha

Try running
nm your_executable | grep getline
and check you're linking against the version in glibc.

U getline@@GLIBC_2.0
Failing that, Falcon's advice to run your program through valgrind is a
good next move.

I think so too..
 
I

InuY4sha

     But you're right: That notion of "line" might not be appropriate
in all circumstances, and it's good to know just what's being counted.

I think this is a bit out of scope, considered the original question..
but it's always a good time to learn something new
 
I

InuY4sha

oK I'll give the whole storyline.. I picked up the first google
results (like this one:http://linux.die.net/man/3/getline) for "man
getline" and they show this "getline" function behaviour which is
always the same -and it works in my code-
Reading the manpage I erroneously thought such function was defined in
the stdlib.. and on the example too, they include stdio and stdlib
only.. the above define "_GNU_SOURCE" stands for something that I
*don't* know so I ignored it (while probably it's the key).

Defining _GNU_SOURCE enables various GNU extensions which aren't part of
the ISO C standards. getline() is one such extension.
Anyway.. the code is this:
[snip]

  //fclose(fp);  //[Argh here I crash ... BUT WHY?]

There's nothing wrong with filelines().

The first possibility which springs to mind is that something else in your
program corrupted the heap (the region of memory used by malloc()) before
filelines() was called.

I don't think that's the case, because, if I avoid geline() calls I
can use as many malloc and free as I want.
If something corrupts the heap, it tends to result in a subsequent call to
malloc() or free() crashing. Heap corruption isn't easy to debug with a
normal debugger (e.g. gdb). valgrind or electric fence may help, although
I'd start by looking for places where you might be overflowing a malloc()d
buffer.

Yes.. I'm not really used to valgrind but I can handle it I guess...
 
I

InuY4sha

Are you sure you're using the version of getline() you think you are?

I've got no idea of how to check on that besides nm exec_file |grep
getline suggestion above which I already answered.
If getline() sets line to point at something *NOT* allocated by
malloc() & friends (e.g. a static buffer, or something in the
*middle* of malloc()ed data), the above line stands a good chance
of corrupting the malloc() arena.

So you're stating it could be a bug..
There is also the possibility that something inside getline() uses
more memory than it allocates, which also can corrupt the malloc()
arena.
 //fclose(fp);  //[Argh here I crash ... BUT WHY?]

And since fclose() is likely to call free() to free a buffer or a FILE
object or something, this is likely to segfault if the malloc() arena
is corrupted.

I also thought so.. but the thing is, that if I don't call the fclose,
I can call subsequent malloc and free (and viceversa) without having
troubles.. which smells fishy...
 
R

Richard Bos

InuY4sha said:
Anyway.. the code is this:
[snip]

=A0 //fclose(fp); =A0//[Argh here I crash ... BUT WHY?]

There's nothing wrong with filelines().

The first possibility which springs to mind is that something else in your
program corrupted the heap (the region of memory used by malloc()) before
filelines() was called.

I don't think that's the case, because, if I avoid geline() calls I
can use as many malloc and free as I want.

That doesn't contradict Nobody's suggestion. All it means is that
getline() makes the error observable, presumably because it, too,
interacts with the heap.

Richard
 
N

Nick Keighley

     But if all you're trying to do is count lines, you don't need
all this machinery anyhow.  

Unfortunately not.. what I want to do is a bit more complicated:
1) Count the N lines of a file
2) Generate a char **lines = malloc(sizeof(char*)*N);
3) Setting lines[x] = NULL and passing it to getlines
4) Parse it
5) Update the lines when necessary and store it back.

The nice thing here is that I have the file splitted in lines so it's
easier to handle it.

that's two passes on the file. Perhaps an array is not the best
data structure. Could you get by with a linked list? Or even
build the linked list as you count the lines then copy the
elements into an array.
So that "getline" function, which malloc-ate the char arrays to the
correct size in my place and does everything *really* is a convenient
toy (imho).
The sample code I gave you was the smallest piece where I used it
(which takes care of point 1 in the above list of tasks.

WHILE more lines
line := read_line()
line_list.add (line)
line_count ++

line_array := malloc (line_count)

FOR ALL i IN line_list
line_array := line_list.remove()
 
G

Guest

| I don't get the reason after using getline() on a FILE* I can't close
| the file (I get a segfault).
| I'mlooking at the function source and I see it calls getdelim()
| function.. which doesn't seem to close the file... wondering why..

Are you passing a buffer that was allocated by malloc() to getline() in the
pointer pointed to by the first argument? If not, that is where your trouble
is. The getline() function can call realloc() on the buffer to enlarge it.
That will fail for static and automatic (including alloca() created) storage.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,049
Latest member
Allen00Reed

Latest Threads

Top