Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   segfault w/ block, but not file scope (http://www.velocityreviews.com/forums/t440779-segfault-w-block-but-not-file-scope.html)

Dieter 01-06-2006 03:30 AM

segfault w/ block, but not file scope
 
Hi.

In the snippet of code below, I'm trying to understand why when the

struct dirent ** namelist

is declared with "file" scope, I don't have a problem freeing the
allocated memory. But when the struct is declared in main (block scope)
it will segfault when passing namelist to freeFileNames().

Since this seems to be just a matter of my understanding scope and
pointer parameter passing better, I only included what thought to be
relevant code. I'll happily provide compilable code if deemed necessary.

Please see commented lines:


struct dirent **namelist; /* file scope works */

int main(void)
{
/* struct dirent **namelist */ /* block scope doesn't work */
int n;

n = getFileNames(H5DIR, namelist); /* included from mylib.h */
freeFileNames(namelist, n); /* included from mylib.h */

return 0;
}


Thank you very much for your comments,
Dieter

Dieter 01-06-2006 03:44 AM

Re: segfault w/ block, but not file scope
 
Dieter wrote:
> Hi.
>
> In the snippet of code below, I'm trying to understand why when the
>
> struct dirent ** namelist
>
> is declared with "file" scope, I don't have a problem freeing the
> allocated memory. But when the struct is declared in main (block scope)
> it will segfault when passing namelist to freeFileNames().
>
> Since this seems to be just a matter of my understanding scope and
> pointer parameter passing better, I only included what thought to be
> relevant code. I'll happily provide compilable code if deemed necessary.
>
> Please see commented lines:
>
>
> struct dirent **namelist; /* file scope works */
>
> int main(void)
> {
> /* struct dirent **namelist */ /* block scope doesn't work */
> int n;
>
> n = getFileNames(H5DIR, namelist); /* included from mylib.h */
> freeFileNames(namelist, n); /* included from mylib.h */
>
> return 0;
> }
>
>
> Thank you very much for your comments,
> Dieter


Here's the actual code if needed. Although dirent.h is platform
specific, I think my question is relative to standard C.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <errno.h>

#define H5DIR "/home/stella/data/h5/rawTables"

int getFileNames(char *directory, struct dirent **namelist);
int freeFileNames(struct dirent **namelist, int entries);

struct dirent **namelist;

int main(void)
{
int n;

n = getFileNames(H5DIR, namelist);
printf("%d\n",n);
err = freeFileNames(namelist, n);
if (err==0)
printf("There wasn't any files");
return 0;
}

int getFileNames(char *directory, struct dirent **namelist)
{
int n, i;

n = scandir(directory, &namelist, 0, alphasort);
if(n == -1){
perror("scandir returned: ");
exit(1);
}
if(n == 0){
printf("No files found. Quiting.\n\n");
exit(1);
}
for (i=0;i<n;i++){
printf("File: %s\n", namelist[i]->d_name);
}

return n;
}

int freeFileNames(struct dirent **namelist, int entries)
{
int i;

if (namelist == NULL)
return 0;
else{
printf("%d",entries);
for (i = 0; i < entries; i++){
free(namelist[i]);
namelist[i] = NULL;
printf("%d,", i);
}
puts("\n");
free(namelist);
namelist = NULL;
}

return 1;
}

Jack Klein 01-06-2006 04:42 AM

Re: segfault w/ block, but not file scope
 
On Thu, 05 Jan 2006 22:44:27 -0500, Dieter <usenet.stuff@comcast.net>
wrote in comp.lang.c:

> Dieter wrote:
> > Hi.
> >
> > In the snippet of code below, I'm trying to understand why when the
> >
> > struct dirent ** namelist
> >
> > is declared with "file" scope, I don't have a problem freeing the
> > allocated memory. But when the struct is declared in main (block scope)
> > it will segfault when passing namelist to freeFileNames().
> >
> > Since this seems to be just a matter of my understanding scope and
> > pointer parameter passing better, I only included what thought to be
> > relevant code. I'll happily provide compilable code if deemed necessary.
> >
> > Please see commented lines:
> >
> >
> > struct dirent **namelist; /* file scope works */
> >
> > int main(void)
> > {
> > /* struct dirent **namelist */ /* block scope doesn't work */
> > int n;
> >
> > n = getFileNames(H5DIR, namelist); /* included from mylib.h */
> > freeFileNames(namelist, n); /* included from mylib.h */
> >
> > return 0;
> > }
> >
> >
> > Thank you very much for your comments,
> > Dieter

>
> Here's the actual code if needed. Although dirent.h is platform
> specific, I think my question is relative to standard C.


The actual code is not needed, and is indeed off-topic. Your problem
has a great deal to do with how the function scandir(), which is
apparently from dirent.h, deals with pointers.


> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <dirent.h>
> #include <errno.h>
>
> #define H5DIR "/home/stella/data/h5/rawTables"
>
> int getFileNames(char *directory, struct dirent **namelist);
> int freeFileNames(struct dirent **namelist, int entries);
>
> struct dirent **namelist;


When you define this pointer a file scope, it has static storage
duration and is therefore initialized to NULL. When you define it
inside a function, it has automatic storage duration by default and it
not initialized at all.

> int main(void)
> {
> int n;
>
> n = getFileNames(H5DIR, namelist);
> printf("%d\n",n);
> err = freeFileNames(namelist, n);
> if (err==0)
> printf("There wasn't any files");
> return 0;
> }
>
> int getFileNames(char *directory, struct dirent **namelist)
> {
> int n, i;
>
> n = scandir(directory, &namelist, 0, alphasort);


[snip]

On the last line of code above, you pass a pointer to 'namelist'
(therefore a char ***) to scandir(). Presumably this function checks
whether the pointed-to char ** is NULL or not, and if it is NULL, it
allocates the necessary memory. And also presumably, if the
pointed-to char ** is not NULL, it assumes that it points to valid
memory and uses it. At the end you try to free a pointer that was not
allocated.

I would suggest that you study the documentation for the function
scandir() and see what the requirements are for that parameter.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html

Dieter 01-06-2006 05:30 AM

Re: segfault w/ block, but not file scope
 
Jack Klein wrote:
> On Thu, 05 Jan 2006 22:44:27 -0500, Dieter <usenet.stuff@comcast.net>
> wrote in comp.lang.c:
>
>
>>Dieter wrote:
>>
>>>Hi.
>>>
>>>In the snippet of code below, I'm trying to understand why when the
>>>
>>> struct dirent ** namelist
>>>
>>>is declared with "file" scope, I don't have a problem freeing the
>>>allocated memory. But when the struct is declared in main (block scope)
>>>it will segfault when passing namelist to freeFileNames().
>>>
>>>Since this seems to be just a matter of my understanding scope and
>>>pointer parameter passing better, I only included what thought to be
>>>relevant code. I'll happily provide compilable code if deemed necessary.
>>>
>>>Please see commented lines:
>>>
>>>
>>>struct dirent **namelist; /* file scope works */
>>>
>>>int main(void)
>>>{
>>> /* struct dirent **namelist */ /* block scope doesn't work */
>>> int n;
>>>
>>> n = getFileNames(H5DIR, namelist); /* included from mylib.h */
>>> freeFileNames(namelist, n); /* included from mylib.h */
>>>
>>> return 0;
>>>}
>>>
>>>
>>>Thank you very much for your comments,
>>>Dieter

>>
>>Here's the actual code if needed. Although dirent.h is platform
>>specific, I think my question is relative to standard C.

>
>
> The actual code is not needed, and is indeed off-topic. Your problem
> has a great deal to do with how the function scandir(), which is
> apparently from dirent.h, deals with pointers.
>
>
>
>>#include <stdio.h>
>>#include <stdlib.h>
>>#include <string.h>
>>#include <dirent.h>
>>#include <errno.h>
>>
>>#define H5DIR "/home/stella/data/h5/rawTables"
>>
>>int getFileNames(char *directory, struct dirent **namelist);
>>int freeFileNames(struct dirent **namelist, int entries);
>>
>>struct dirent **namelist;

>
>
> When you define this pointer a file scope, it has static storage
> duration and is therefore initialized to NULL. When you define it
> inside a function, it has automatic storage duration by default and it
> not initialized at all.
>
>
>>int main(void)
>>{
>> int n;
>>
>> n = getFileNames(H5DIR, namelist);
>> printf("%d\n",n);
>> err = freeFileNames(namelist, n);
>> if (err==0)
>> printf("There wasn't any files");
>> return 0;
>>}
>>
>>int getFileNames(char *directory, struct dirent **namelist)
>>{
>> int n, i;
>>
>> n = scandir(directory, &namelist, 0, alphasort);

>
>
> [snip]
>
> On the last line of code above, you pass a pointer to 'namelist'
> (therefore a char ***) to scandir(). Presumably this function checks
> whether the pointed-to char ** is NULL or not, and if it is NULL, it
> allocates the necessary memory. And also presumably, if the
> pointed-to char ** is not NULL, it assumes that it points to valid
> memory and uses it. At the end you try to free a pointer that was not
> allocated.
>
> I would suggest that you study the documentation for the function
> scandir() and see what the requirements are for that parameter.
>


Jack, I sincerely thank you for commenting.

NULL initialization was certainly an issue.

Dieter

M.B 01-06-2006 05:47 AM

Re: segfault w/ block, but not file scope
 

Dieter wrote:
> Jack Klein wrote:
> > On Thu, 05 Jan 2006 22:44:27 -0500, Dieter <usenet.stuff@comcast.net>
> > wrote in comp.lang.c:
> >
> >
> >>Dieter wrote:
> >>
> >>>Hi.
> >>>
> >>>In the snippet of code below, I'm trying to understand why when the
> >>>
> >>> struct dirent ** namelist
> >>>
> >>>is declared with "file" scope, I don't have a problem freeing the
> >>>allocated memory. But when the struct is declared in main (block scope)
> >>>it will segfault when passing namelist to freeFileNames().
> >>>
> >>>Since this seems to be just a matter of my understanding scope and
> >>>pointer parameter passing better, I only included what thought to be



> >>>relevant code. I'll happily provide compilable code if deemed necessary.
> >>>
> >>>Please see commented lines:
> >>>
> >>>
> >>>struct dirent **namelist; /* file scope works */
> >>>
> >>>int main(void)
> >>>{
> >>> /* struct dirent **namelist */ /* block scope doesn't work */
> >>> int n;
> >>>
> >>> n = getFileNames(H5DIR, namelist); /* included from mylib.h */
> >>> freeFileNames(namelist, n); /* included from mylib.h */
> >>>
> >>> return 0;
> >>>}
> >>>
> >>>
> >>>Thank you very much for your comments,
> >>>Dieter
> >>
> >>Here's the actual code if needed. Although dirent.h is platform
> >>specific, I think my question is relative to standard C.

> >
> >
> > The actual code is not needed, and is indeed off-topic. Your problem
> > has a great deal to do with how the function scandir(), which is
> > apparently from dirent.h, deals with pointers.
> >
> >
> >
> >>#include <stdio.h>
> >>#include <stdlib.h>
> >>#include <string.h>
> >>#include <dirent.h>
> >>#include <errno.h>
> >>
> >>#define H5DIR "/home/stella/data/h5/rawTables"
> >>
> >>int getFileNames(char *directory, struct dirent **namelist);
> >>int freeFileNames(struct dirent **namelist, int entries);
> >>
> >>struct dirent **namelist;

> >
> >
> > When you define this pointer a file scope, it has static storage
> > duration and is therefore initialized to NULL. When you define it
> > inside a function, it has automatic storage duration by default and it
> > not initialized at all.
> >
> >
> >>int main(void)
> >>{
> >> int n;
> >>
> >> n = getFileNames(H5DIR, namelist);
> >> printf("%d\n",n);
> >> err = freeFileNames(namelist, n);
> >> if (err==0)
> >> printf("There wasn't any files");
> >> return 0;
> >>}
> >>
> >>int getFileNames(char *directory, struct dirent **namelist)
> >>{
> >> int n, i;
> >>
> >> n = scandir(directory, &namelist, 0, alphasort);

> >
> >
> > [snip]
> >
> > On the last line of code above, you pass a pointer to 'namelist'
> > (therefore a char ***) to scandir(). Presumably this function checks
> > whether the pointed-to char ** is NULL or not, and if it is NULL, it
> > allocates the necessary memory. And also presumably, if the
> > pointed-to char ** is not NULL, it assumes that it points to valid
> > memory and uses it. At the end you try to free a pointer that was not
> > allocated.
> >
> > I would suggest that you study the documentation for the function
> > scandir() and see what the requirements are for that parameter.
> >

>
> Jack, I sincerely thank you for commenting.
>
> NULL initialization was certainly an issue.
>
> Dieter


I guess this is a scope issue for variable "namelist"
I suggest to change the function
int getFileName(char *,struct dirent ***);
and make necessary changes to code.
it may work fine

bcoz scandir i guess sets "struct dirent **" itself.
if its global all is fine, but local variables 0 its problem-same as
pass by value

thanks
-M.B


M.B 01-06-2006 05:51 AM

Re: segfault w/ block, but not file scope
 
please chanmge function int getFileName(char *,struct dirent **);
to int getFileNames(char *,struct dirent ***) and make necessary
changes to code to accomodate this

its a pass by value v/s pass by reference issue


Chuck F. 01-06-2006 06:35 AM

Re: segfault w/ block, but not file scope
 
Dieter wrote:
> Jack Klein wrote:
>
>> [snip]
>>
>> On the last line of code above, you pass a pointer to
>> 'namelist' (therefore a char ***) to scandir(). Presumably
>> this function checks whether the pointed-to char ** is NULL or
>> not, and if it is NULL, it allocates the necessary memory.
>> And also presumably, if the pointed-to char ** is not NULL, it
>> assumes that it points to valid memory and uses it. At the
>> end you try to free a pointer that was not allocated.
>>
>> I would suggest that you study the documentation for the
>> function scandir() and see what the requirements are for that
>> parameter.

>
> Jack, I sincerely thank you for commenting.
>
> NULL initialization was certainly an issue.


All of which points out why we want queries to be topical. Once
you involve an unknown header (dirent) and an unknown function
(scandir) nobody can have any accurate idea what goes on. This is
why this whole thread should have been on a newsgroup dealing with
your system in the first place.

The fact that Jack could make an educated guess does not affect
this. His guess could well have been total nonsense, and could
have missed important factors. There is (in principle) noone here
to correct any mistakes.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>

Chris Torek 01-06-2006 06:59 AM

Re: segfault w/ block, but not file scope
 
In article <SZWdnSAon_epeSDenZ2dnUVZ_tSdnZ2d@comcast.com>
Dieter <usenet.stuff@comcast.net> wrote:
>struct dirent **namelist; /* file scope works */
>
>int main(void)
>{
> /* struct dirent **namelist */ /* block scope doesn't work */
> int n;
>
> n = getFileNames(H5DIR, namelist); /* included from mylib.h */


This passes the *value* of the variable "namelist" to the function.
If namelist has block scope, the variable is also automatic, and hence
uninitialized, and hence contains garbage. If namelist has file
scope, the variable also has static duration and hence is
initialized to NULL.

In any case, getFileNames() cannot change the value stored in
the variable named "namelist" (unless it does not declare one
of its own, and does access the file-scope one). So it makes
no sense to pass the value in the first place, if namelist is
a block-scope variable.

If getFileNames() needs to modify namelist, it will need the
address of the variable:

extern int getFileNames(first_type, struct dirent ***);
...
int main(void) {
struct dirent **namelist;
int n;

/* optional: namelist = NULL; */
n = getFileNames(H5DIR, &namelist);

> freeFileNames(namelist, n); /* included from mylib.h */


Presumably the NULL-initialized file-scope static-duration version
causes freeFileNames() to be a no-op. Passing the uninitialized
value of the block-scope version presumably does not.

> return 0;
>}

--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.

M.B 01-06-2006 06:59 AM

Re: segfault w/ block, but not file scope
 
sorry if thjis is a duplicate reply...

I guess this is a scope issue for variable "namelist"
I suggest to change the function
int getFileName(char *,struct dirent ***);
and make necessary changes to code.
it may work fine

bcoz scandir i guess sets "struct dirent **" itself.
if its global all is fine, but local variables 0 its problem-same as
pass by value

thanks
-M.B


M.B 01-06-2006 07:02 AM

Re: segfault w/ block, but not file scope
 
please check
pass by value
v/s pass by ref/pointers carefully


hope this helps to solve the issue



All times are GMT. The time now is 05:25 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.