LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-07-2006, 06:07 PM   #1
slanted
LQ Newbie
 
Registered: Nov 2006
Posts: 7

Rep: Reputation: 0
C problem


I'm having trouble figuring out why the value of one of my vars is being changed

Code:
#include <unistd.h>
#include <dirent.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>

typedef struct file {
        char *name;
        int size;
} File;

struct directory {
        char *name;
        int size;
        int nfiles;
        int ndirs;
        struct directory *parent;
        struct directory *dlist[1];
        File *flist[1];
};

void print_dir_files(struct directory *d)
{
        int i, nfiles;

        nfiles = d->nfiles;

        if (nfiles > 0)
        {
                for (i = 0; i < nfiles; i++)
                {
                        printf("%s ", (d->flist[i])->name);
                }
                printf("\n");
        }
}

void print_dir_dirs(struct directory *d)
{
        int i, ndirs;

        ndirs = d->ndirs;

        if (ndirs > 0)
        {
                for (i = 0; i < ndirs; i++)
                {
                        printf("%s ", (d->dlist[i])->name);
                }
                printf("\n");
        }
}

int dir_add_file(struct directory *d, File *f)
{
        int nfiles;
        File **temp;

        nfiles = d->nfiles;

//      if ((temp = (File **)realloc(sizeof(File *) * (nfiles + 1))) == NULL)
//      {
//              printf("Memory Error\n");
//              return -1;
//      }

//      d->flist = temp;

        d->flist[nfiles] = f;

        d->size += f->size;
        d->nfiles++;

        return 1;
}

int dir_add_dir(struct directory *d, struct directory *new)
{
        int ndirs;

        ndirs = d->ndirs;

        d->dlist[ndirs] = new;

        d->size += new->size;
        d->ndirs++;

        return 1;
}

void print_dir_info(struct directory *d)
{
        printf("DIRECTORY %s\n", d->name);
        printf("SIZE: %d in %d files and %d dirs\n", d->size, d->nfiles, d->ndirs);
}

File *create_file(char *name, int size)
{
        File *f;

        f = (File *)malloc(sizeof(FILE));

        if (f == NULL)
        {
                printf("Memory Error\n");
                return NULL;
        }

        f->name = (char *)malloc(sizeof(char) * strlen(name));

        if (f->name == NULL)
        {
                printf("Memory Error\n");
                return NULL;
        }

        strcpy(f->name, name);
        f->size = size;

        return f;
}

struct directory *initialize_dir(struct directory *dir, char *name)
{

                if ((dir = malloc(sizeof(struct directory))) == NULL)
                {
                        printf("Memory Error\n");
                        return NULL;
                }

                dir->name = (char *)malloc(sizeof(char) * strlen(name));

                if (dir->name == NULL)
                {
                        printf("Memory Error\n");
                        return NULL;
                }

                strcpy(dir->name, name);

                dir->size = 0;
                dir->nfiles = 0;
                dir->ndirs = 0;

                return dir;
}

int process_dir(char *path, struct directory *dir)
{
        unsigned int fd;
        char *fpath;
        DIR *dir_ptr;
        struct dirent *dir_ent_ptr;
        struct stat buffer;
        File *new_file;
        struct directory *new_dir;

        if ((dir_ptr = opendir(path)) != NULL)
        {

                dir = initialize_dir(dir, path);

                while (dir_ent_ptr = readdir(dir_ptr))
                {

                        if (strcmp(dir_ent_ptr->d_name, ".") == 0)
                                continue;

                        if (strcmp(dir_ent_ptr->d_name, "..") == 0)
                                continue;

                        fpath = (char *)malloc(sizeof(char) * (strlen(path) + strlen(dir_ent_ptr->d_name)));

                        if (fpath == NULL)
                        {
                                printf("Memory Error\n");
                                return -1;
                        }

                        if (strcmp(path, "/") == 0)
                                sprintf(fpath, "%s%s", path, dir_ent_ptr->d_name);
                        else
                                sprintf(fpath, "%s/%s", path, dir_ent_ptr->d_name);

                        if (stat(fpath, &buffer) < 0)
                        {
                                perror("file stat");
                        }

                        if (S_ISLNK(buffer.st_mode))
                        {
                                printf("LINK\n");
                        }

                        else if (S_ISDIR(buffer.st_mode))
                        {
                        printf("1. %s\n", fpath);

                                new_dir = initialize_dir(new_dir, dir_ent_ptr->d_name);
                        printf("2. %s\n", fpath);

                                new_dir->size = process_dir(fpath, new_dir);
                        printf("3. %s\n", fpath);

                                dir_add_dir(dir, new_dir);
                        }

                        else if (S_ISREG(buffer.st_mode))
                        {
                                new_file = create_file(dir_ent_ptr->d_name, buffer.st_size);

                                if (new_file == NULL)
                                {
                                        return -1;
                                }

                                if (dir_add_file(dir, new_file) < 0)
                                {
                                        return -1;
                                }

                        }
                }
        }

        closedir(dir_ptr);

        return dir->size;
}

int main (int argc, char **argv)
{
        struct directory *root;
        int rv;

        if ((rv = process_dir(argv[1], root) < 0))
                printf("ERROR\n");

//      print_dir_info(root);

        return 0;
}
example output is
1. /home/username
2. /home/usernam!
3. /home/usernam!

I don't understand how fpath is being changed by calling initialize_dir

Last edited by slanted; 11-07-2006 at 06:18 PM.
 
Old 11-07-2006, 08:36 PM   #2
nadroj
Senior Member
 
Registered: Jan 2005
Location: Canada
Distribution: ubuntu
Posts: 2,539

Rep: Reputation: 60
is it for sure this function?
if you comment out
Code:
                      new_dir = initialize_dir(new_dir, dir_ent_ptr->d_name);
                        printf("2. %s\n", fpath);
does it still produce the behavior?

also does it always replace the last character with ! or is it something different?
 
Old 11-07-2006, 09:10 PM   #3
slanted
LQ Newbie
 
Registered: Nov 2006
Posts: 7

Original Poster
Rep: Reputation: 0
yeah I'm sure it was that function.
I commented out the code in the function and fpath stayed the same

I've fixed the problem by changing process_dir from allocating memory to fpath myself to having it a static character arrary.

so instead of char *fpath; fpath = malloc(etc.......)
its

char fpath[MAXPATHLEN]

unfortunatley this isn't as efficient as the first way I tryed.
since paths are of variable length.
but it does work

I'd still like to know why memory allocated to fpath was changed or corrupted by a function that was outside the scope of that variable.
and shouldn't have access to it.
 
Old 11-07-2006, 10:29 PM   #4
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Hi -

What's this?
Code:
// SUSPICIOUS....
f->name = (char *)malloc(sizeof(char) * strlen(name));
Wouldn't you prefer this?
Code:
f->name = (char *)malloc(strlen(name) + 1);
 
Old 11-07-2006, 10:57 PM   #5
slanted
LQ Newbie
 
Registered: Nov 2006
Posts: 7

Original Poster
Rep: Reputation: 0
yup I changed that while I was trying to figure out the other problem to
malloc(sizeof(char) * (strlen(name) + 1));

you could leave out the sizeof(char) since it is just 1
but that's just he way I was taught and I guess its good if the size of a char was to ever change for some reason. thanks for the input
 
Old 11-07-2006, 11:38 PM   #6
tuxdev
Senior Member
 
Registered: Jul 2005
Distribution: Slackware
Posts: 2,012

Rep: Reputation: 115Reputation: 115
sizeof(char) is always one, by definition. The only good reason (and it is a good reason) is to make explicit what you are malloc()ing.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
perl problem? apache problem? cgi problem? WorldBuilder Linux - Software 1 09-17-2003 07:45 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:09 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration