簡體   English   中英

Valgrind:大小為8的無效讀/寫

[英]Valgrind: Invalid read/write of size 8

我是一名新手C學生,正在嘗試編寫目錄樹。 沒問題,但Valgrind不贊成。 我已經閱讀過有關類似問題的文章,但似乎無法弄清楚。

我不僅會提供摘要以使其起作用,而且還會解釋我在做什么錯,從而極大地貼上答案,這樣以后我就不會再遇到同樣的問題了。 對於為什么代碼通常不好的反饋也不會被忽略:)

這些是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;
}

您僅分配了足夠的空間來指向file_n的指針:

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

正確的方法是執行此操作(無需進行強制轉換,這是不必要的):

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM