2012-03-30 79 views
2

我是一名试图编写目录树的新手C学生。它工作没问题,但Valgrind不赞同。我已阅读关于类似问题的帖子,但似乎无法弄清楚。Valgrind:无效的读写大小为8

我会大大appriciate答案不仅一个片段,使其工作,但也是一个解释我做错了,所以我不会在未来有同样的问题。为什么代码是一般的差反馈不会忽视任何:)

这些是从Valgrind的错误(乘以处理项目的金额):

==10463== Invalid write of size 8 
==10463== at 0x400C5D: checkDir (dirtree.c:96) 
==10463== by 0x400F53: main (dirtree.c:135) 
==10463== Address 0x51f88d8 is 0 bytes after a block of size 8 alloc'd 
==10463== at 0x4C28F9F: malloc (vg_replace_malloc.c:236) 
==10463== by 0x400BED: checkDir (dirtree.c:93) 
==10463== by 0x400F53: main (dirtree.c:135) 

==10463== Invalid read of size 8 
==10463== at 0x4ECFF28: __tz_convert (tzset.c:627) 
==10463== by 0x4ECD728: ctime (ctime.c:32) 
==10463== by 0x401022: main (dirtree.c:147) 
==10463== Address 0x51f88d8 is 0 bytes after a block of size 8 alloc'd 
==10463== at 0x4C28F9F: malloc (vg_replace_malloc.c:236) 
==10463== by 0x400BED: checkDir (dirtree.c:93) 
==10463== by 0x400F53: main (dirtree.c:135) 

而且她是代码(少了一份叠码):

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <time.h> 

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

#define MAX_PATH_LENGTH 500 
#define MAX_ITEM_LENGTH 5000 
#define MAX_ITEM_CNT 1000 

typedef struct dirent dirent; 
typedef struct file_s { 
    char *name; 
    time_t mtime; 
} file_n; 
typedef struct itemss { 
    int filecnt; 
    file_n *files[sizeof(char*)*MAX_ITEM_CNT]; 
    int dircnt; 
    char *dirs[sizeof(char*)*MAX_ITEM_CNT];    
} items; 
typedef stack_node_s* stack_s; 

void stack_init(stack_s *stack){ 
    *stack = NULL; 
} 

/* Pushes item to a stack pointed by parameter stack. Returns 0 if succesful, 
* -1 otherwise. 
*/ 
int stack_push(void *p, stack_s *stack){ 
    stack_node_s *newitem = malloc(sizeof(stack_node_s)); 
    if (!newitem) return -1; 
    newitem->value = p; 
    newitem->next = *stack; 
    *stack = newitem; 
    return 0; 
} 

/* Pops item from a stack pointed by parameter stack. Returns pointer to 
* element removed from stack if succesful, null if there is an error or 
* the stack is empty. 
*/ 
void *stack_pop(stack_s *stack){ 
    if(!*stack) return NULL; 
    stack_node_s *freethis = *stack; 
    void *returnp = freethis->value; 
    *stack = (*stack)->next; 
    free(freethis); 
    return returnp; 
} 

int isDir(char *dirname){ 
    struct stat stbuf; 
    stat(dirname, &stbuf); 
    return S_ISDIR(stbuf.st_mode); 
} 

time_t mtime(char *dirname){ 
    struct stat stbuf; 
    stat(dirname, &stbuf); 
    return stbuf.st_mtime; 
} 

void checkDir(char* path, stack_s **stack, items *list){ 
    DIR *stream; 
    char fullpath[MAX_PATH_LENGTH]; 

    if(!(stream = opendir(path))){ 
    return; 
    } 
    struct dirent *dir; 
    while((dir = readdir(stream))){ 
    strcpy(fullpath, path); 
    strcat(fullpath, "/"); 
    if(strcmp(dir->d_name, ".") && strcmp(dir->d_name, "..")){ 
     char *savedpath = (char*) malloc(sizeof(char)*MAX_ITEM_LENGTH); 
     strcat(fullpath, dir->d_name); 
     strcpy(savedpath,fullpath); 
     if(isDir(savedpath)){ 
    list->dirs[(list->dircnt)++] = savedpath; 
    stack_push(savedpath,stack); 
     } 
     else{ 
    file_n *new = (file_n*) malloc(sizeof(file_n*)); 
    list->files[(list->filecnt)] = new; 
    (list->files[(list->filecnt)])->name = savedpath; 
    (list->files[(list->filecnt)])->mtime = mtime(savedpath); 
    (list->filecnt)++; 
     } 
    } 
    } 
    closedir(stream); 
    char *popped; 
    while(popped = (char*)stack_pop(stack)){ 
    checkDir(popped,stack,list); 
    } 
} 

int qsortcbdir(const void* a, const void* b){ 
    const char **ia = (const char **)a; 
    const char **ib = (const char **)b; 
    return strcmp(*ia, *ib); 
} 

int qsortcbfile(const void* a, const void* b){ 
    const file_n **ia = (const file_n **)a; 
    const file_n **ib = (const file_n **)b; 
    int timea = (int) (**ia).mtime; 
    int timeb = (int) (**ib).mtime; 
    if(timea == timeb) 
     return strcmp((**ia).name, (**ib).name); 
    return timea - timeb; 
} 

int main(int argc, char* argv[]){ 
    if(argc != 2){ 
    printf("Incorrect number of arguments, exiting.\n"); 
    return -1; 
    } 
    stack_s stack; 
    stack_init(&stack); 
    items *list = (items*)malloc(sizeof(items)); 
    list->dircnt = (list->filecnt = 0); 
    memset(list->dirs, 0, sizeof(char*)*MAX_ITEM_CNT); 
    memset(list->files, 0, sizeof(char*)*MAX_ITEM_CNT); 
    checkDir(argv[1], &stack, list); 

    qsort(list->dirs,list->dircnt,sizeof(char*), &qsortcbdir); 
    for(int i=0;i < list->dircnt;i++){ 
    printf("%s\n", list->dirs[i]); 
    free(list->dirs[i]); 
    } 
    printf("---\n"); 

    qsort(list->files,list->filecnt,sizeof(file_n*), &qsortcbfile); 
    for(int i=0;i < list->filecnt;i++){ 
    printf("path: %s, mtime: %s", (list->files[i])->name, ctime(&((list->files[i])->mtime))); 
    free((list->files[i])->name); 
    free(list->files[i]); 
    } 
    free(list); 

    return EXIT_SUCCESS; 
} 

回答

5

你只file_n分配的指针足够的空间:

file_n *new = (file_n*) malloc(sizeof(file_n*)); 

正确的方法是做到这一点(和离开了剧组,这是不必要的):

file_n *new = malloc(sizeof(file_n)); 
+3

或者交替,'file_n *新的=的malloc(*的sizeof新);' – caf 2012-03-31 02:43:40