Thread: Structure Clobering

  1. #1
    Registered User
    Join Date
    May 2004
    Posts
    3

    Angry Structure Clobering

    I am writing a file integrity program. I first scans through all of the directories, gathering file names. The problem I am having is in storing the file name and directory names. File names seem to bleed into the directory tree. The first 0a-9a directories are correct ,but once I hit the bottom of the fuction the files have bleed through. Attached is the entire source code, if you feel the the code sections I have posted are not enough.

    Code:
     D:\tmp\0a\
     D:\tmp\1a\
     D:\tmp\2a\
     D:\tmp\3a\
     D:\tmp\4a\
     D:\tmp\5a\
     D:\tmp\6a\
     D:\tmp\7a\
     D:\tmp\8a\
     D:\tmp\9a\
     D:\tmp\u.txt
     D:\tmp\v.txt
     D:\tmp\w.txt
     D:\tmp\x.txt
     D:\tmp\y.txt
     D:\tmp\z.txt
     D:\tmp\6a\
     D:\tmp\7a\
     D:\tmp\8a\
     D:\tmp\9a\
    Code:
     struct File {
     	
     	int i_files;
     	int a_files;
     	char **files;
     };
     
     struct Directory {
     	
     	int i_dirs;
     	int a_dirs;
     	char **dirs;
     };

    The following code add directories to a Directory structure and files to a File structure. It does not show the initialization of the structures.

    Code:
     	while ((file = readdir(dir_in)) != NULL) {
     
     		if (!((dir_in->dd_dta).attrib == _A_SUBDIR)) {
     
     			if (wfiles->i_files >= wfiles->a_files) {
     				wfiles->files =
     					realloc(wfiles->files,
     		    		    wfiles->a_files + MIN_FILE_ALLOC);
     				if (wfiles->files == NULL) {
     					fprintf(stderr,
     		    			"Something really bad just happend. We lost the file list in realloc.\n");
     					return NULL;
     				}
     				wfiles->a_files += MIN_FILE_ALLOC;
     			}
     
     			wfiles->files[wfiles->i_files] =
     				calloc(MAX_FILE_NAME, sizeof(char));
     			if (wfiles->files[wfiles->i_files] == NULL) {
     				fprintf(stderr, "File name too long.\n");
     				return NULL;
     			}
     			strncpy(wfiles->files[wfiles->i_files], directory,
     				DIR_IN_LEN);
     			strncpy(wfiles->files[wfiles->i_files] + DIR_IN_LEN,
     				"\\", 1);
     			strncpy(wfiles->files[wfiles->i_files] + DIR_IN_LEN + 1,
     				file->d_name, file->d_namlen);
     			wfiles->i_files++;
     
     		} else {
     
     			if (wdirs->i_dirs >= wdirs->a_dirs) {
     				wdirs->dirs =
     					realloc(wdirs->dirs,
     		    		    wdirs->a_dirs + MIN_FILE_ALLOC);
     				if (wdirs->dirs == NULL) {
     					fprintf(stderr,
     		    			"Something really bad just happend. We lost the directory list in realloc.\n");
     					return NULL;
     				}
     				wdirs->a_dirs += MIN_FILE_ALLOC;
     				printf("%i\t%i\n", wdirs->a_dirs,
     		    		   wdirs->i_dirs);
     			}
     
     			if (strcmp(file->d_name, ".") != 0
     				&& strcmp(file->d_name, "..") != 0) {
     				wdirs->dirs[wdirs->i_dirs] =
     		    		malloc(MAX_FILE_NAME * sizeof(char));
     				if (wdirs->dirs[wdirs->i_dirs] == NULL) {
     					fprintf(stderr,
     		    			"Unable to malloc(MAX_FILE_NAME * sizeof( char )).\n");
     					return NULL;
     				}
     				if (memset
     		    	    (wdirs->dirs[wdirs->i_dirs], '\0',
     					 MAX_FILE_NAME) == NULL) {
     					fprintf(stderr,
     		    			"We had some problem with memset.\n");
     					return NULL;
     				}
     				strncpy(wdirs->dirs[wdirs->i_dirs], directory,
     					DIR_IN_LEN);
     		    	strncpy(wdirs->dirs[wdirs->i_dirs] + DIR_IN_LEN,
     					"\\", 1);
     				strncpy(wdirs->dirs[wdirs->i_dirs] +
     					DIR_IN_LEN + 1, file->d_name,
     					file->d_namlen);
     				strncpy(wdirs->dirs[wdirs->i_dirs] +
     		    		DIR_IN_LEN + file->d_namlen + 1, "\\",
     					1);
     				printf("%s\n", wdirs->dirs[wdirs->i_dirs]);
     				wdirs->i_dirs++;
     			}
     		}
     
     	}

  2. #2
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    You are experiencing the unpredictable results of a buffer overrun.
    Code:
    wfiles->files = realloc(wfiles->files, wfiles->a_files + MIN_FILE_ALLOC);
    should be:
    Code:
     wfiles->files = realloc(wfiles->files, (wfiles->a_files + MIN_FILE_ALLOC) * sizeof(*wfiles->files));
    The same for other places where you allocate memory.

    Welcome to the forums!

  3. #3
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Also, using realloc in the following manner is not a good thing to do.
    Code:
    ptr = realloc(ptr, elements * sizeof *ptr);
    It is better to use another temporary pointer.
    Code:
    temp = realloc(ptr, elements * sizeof *ptr);
    if ( temp != NULL )
    {
       ptr = temp;
    }
    else
    {
       free(ptr);
       /* etc. */
    }
    Then if the realloc call failed, you don't leak the memory you started with.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  4. #4
    Registered User
    Join Date
    May 2004
    Posts
    3
    Dave_Sinkula:
    Thanks for the reminder. It slipped my mind completly. 8^)

    anonytmouse:
    I added you suggestion and it did not change anything. I do need to add a sizeof but for char, as the wfiles->a_files variable holds how many chars have been allocated. Thanks for the help.

  5. #5
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    >> I do need to add a sizeof but for char, as the wfiles->a_files variable holds how many chars have been allocated. <<

    No, wfiles->files holds an array of character pointers. Therefore, you have to multiply the desired number of entries by sizeof(char *). Multiplying by sizeof(char) will give you one quarter of the memory that you need(char being one byte while char * is 4 bytes on Win32). This same error is made in your calls to calloc.

    These are all wrong:
    Code:
    	wfiles->files = calloc(MIN_FILE_ALLOC, sizeof(char));
    	wdirs->dirs = calloc(MIN_FILE_ALLOC, sizeof(char));
    
    	char **test = calloc(MIN_FILE_ALLOC, sizeof(char));
    	for (int a = 0; a < MIN_FILE_ALLOC; a++) {
    		test[a] = calloc(MAX_FILE_NAME, sizeof(char));
    	}
    Check all your calls to calloc(), malloc() and realloc().

  6. #6
    Registered User
    Join Date
    May 2004
    Posts
    3
    I feel soooo very slow some times. 8^) Thanks for pointing that out. I will go through the code and see if that fixes it.

    [edit] Now I feel really slow as that seems to have fixed it. Thanks for all the help.[/edit]

    jInuQ
    Last edited by jInuQ; 05-18-2004 at 02:40 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem referencing structure elements by pointer
    By trillianjedi in forum C Programming
    Replies: 19
    Last Post: 06-13-2008, 05:46 PM
  2. Replies: 5
    Last Post: 02-14-2006, 09:04 AM
  3. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  4. Serial Communications in C
    By ExDigit in forum Windows Programming
    Replies: 7
    Last Post: 01-09-2002, 10:52 AM
  5. C structure within structure problem, need help
    By Unregistered in forum C Programming
    Replies: 5
    Last Post: 11-30-2001, 05:48 PM