2016-05-17 2 views
-1

Все в моем коде работает правильно, за исключением того, что функция freeFunc останавливает выполнение, и я не знаю почему.Свободная функция не бесплатна в c

void orderTheFiles(char* path) 
{ 
    int i = 0; 
    DIR * dir = opendir(path); 
    DIR * exampleDir = opendir(path); 
    int length = checkHowMuchFiles(exampleDir); 
    if (length != EXIT) 
    { 
     char** arr = (char**)calloc(length,sizeof(char*)); 
     dynamicFunc(arr, length); 
     openDirectory(dir, arr); 
     freeFunc(arr, length); 
    } 

} 

checkHowMuchFiles функция действительно не имеет значения, как хорошо, но это работает.

Вот dynamicFunc:

void dynamicFunc(char** arr, int length) 
{ 
    int i = 0; 
    for (; i < length; i++) 
    { 
     arr[i] = calloc(MAX_LENGTH_OF_STRING,sizeof(char)); 
    } 
} 

Я попытался открыть каталог с этой функцией и положить целые имена файлов внутри динамического массива, и перераспределить массив по длине строки:

int openDirectory(DIR * dir, char** arr) 
{ 
    int flag = 0; 
    int i = 0; 
    struct dirent *ent; 
    if ((dir== NULL)) 
    { 
     printf("Sorry can't open the directory\n"); 
     flag = 1; 
    } 
    else 
    { 
     while (i < NUMBER_OF_GRABADGE_FILES) 
     { 
      readdir(dir); //This line deletes our garbage files like '.' and '..' (maybe it's just on my computer) 
      i++; 
     } 
     i = 0; 
     while ((ent = readdir(dir)) != NULL) 
     { 
      arr[i] = realloc(arr[i], (sizeof(char)*ent->d_namlen) + 1); 
      strncpy(arr[i], ent->d_name, MAX_LENGTH_OF_STRING); 
      printf("%s\n", arr[i]); 
      i++; 
     } 

    } 
    closedir(dir); 
    return flag; 
} 

свободная функция:

void freeFunc(char** arr, int length) 
{ 
    int i = 0; 
    for (; i < length; i++) 
    { 
     free(arr[i]); 
    } 
    free(arr); 
} 

примечание: Я нас ed dirent.h

+4

Где код 'freeFunction'? – kfx

+2

Как мы ожидаем, чтобы помочь вам отладить 'freeFunc()', если вы не показываете нам код? –

+4

'strncpy (arr [i], ent-> d_name, MAX_LENGTH_OF_STRING);': 'MAX_LENGTH_OF_STRING' выглядит плохо. – BLUEPIXY

ответ

0

Похоже, что я неправильно прочитал код; нет утечки памяти, но возникла проблема в том, что BLUEPIXYnoted.

Вот мой продезинфицировать, завершен, тестируются valgrind -clean кода:

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

enum { MAX_LENGTH_OF_STRING = 256 }; 

static int checkHowManyFiles(const char *path) 
{ 
    assert(path != 0); 
    return 100; 
} 

static void oom(void) 
{ 
    fprintf(stderr, "Out of memory!\n"); 
    exit(EXIT_FAILURE); 
} 

static void dynamicFunc(char** arr, int length) 
{ 
    int i = 0; 
    for (; i < length; i++) 
    { 
     if ((arr[i] = calloc(MAX_LENGTH_OF_STRING,sizeof(char))) == 0) 
      oom(); 
    } 
} 

enum { NUMBER_OF_GRABADGE_FILES = 2 }; 

static int openDirectory(DIR * dir, char** arr, int num_files) 
{ 
    int flag = 0; 
    int i = 0; 
    struct dirent *ent; 
    if ((dir== NULL)) 
    { 
     printf("Sorry can't open the directory\n"); 
     flag = -1; 
    } 
    else 
    { 
     /* Skip . and .. */ 
     for (i = 0; i < NUMBER_OF_GRABADGE_FILES; i++) 
     { 
      if (readdir(dir) == 0) 
       break; 
     } 
     for (i = 0; i < num_files && (ent = readdir(dir)) != NULL; i++) 
     { 
      /* d_namlen is not mandated by POSIX (only d_name, d_ino are) */ 
      size_t namlen = strlen(ent->d_name) + 1; 
      arr[i] = realloc(arr[i], namlen); 
      if (arr[i] == 0) 
       oom(); 
      strncpy(arr[i], ent->d_name, namlen); 
      printf("%d [%s]\n", i, arr[i]); 
     } 
     flag = i; 
    } 
    closedir(dir); 
    return flag; 
} 

static void freeFunc(char** arr, int length) 
{ 
    int i = 0; 
    for (; i < length; i++) 
    { 
     free(arr[i]); 
    } 
    free(arr); 
} 

static void orderTheFiles(char* path) 
{ 
    DIR * dir = opendir(path); 
    int length = checkHowManyFiles(path); 
    printf("Will assume there are no more than %d files\n", length); 
    if (length > 0) 
    { 
     char** arr = (char**)calloc(length,sizeof(char*)); 
     dynamicFunc(arr, length); 
     int n = openDirectory(dir, arr, length); 
     printf("Actually got %d files\n", n); 
     freeFunc(arr, length); 
    } 
    else 
     closedir(dir); 
} 

int main(void) 
{ 
    orderTheFiles("."); 
    return 0; 
} 

Примечания пересмотренного интерфейс checkHowManyFiles() - который переименован - и тривиальная реализация используется. В одной из директорий, где я тестировал код, есть более 100 файлов, и всего 5 в другой.

$ ../di19 
==3546== Memcheck, a memory error detector 
==3546== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. 
==3546== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info 
==3546== Command: ../di19 
==3546== 
Will assume there are no more than 100 files 
0 [aes] 
1 [aes.c] 
2 [aes.dSYM] 
3 [aes.h] 
4 [makefile] 
Actually got 5 files 
==3546== 
==3546== HEAP SUMMARY: 
==3546==  in use at exit: 26,329 bytes in 187 blocks 
==3546== total heap usage: 380 allocs, 193 frees, 63,291 bytes allocated 
==3546== 
==3546== LEAK SUMMARY: 
==3546== definitely lost: 0 bytes in 0 blocks 
==3546== indirectly lost: 0 bytes in 0 blocks 
==3546==  possibly lost: 0 bytes in 0 blocks 
==3546== still reachable: 0 bytes in 0 blocks 
==3546==   suppressed: 26,329 bytes in 187 blocks 
==3546== 
==3546== For counts of detected and suppressed errors, rerun with: -v 
==3546== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) 
$ 

Код теперь убеждается, что он не выходит из пределов. Поскольку POSIX устанавливает только d_name и d_ino в структуре struct dirent, я использовал strlen(ent->d_name) для определения длины имени. Вы сами можете решить, важен ли для вас уровень мобильности - большинство систем, вероятно, обеспечивают d_namlen. Обратите внимание, что функция openDirectory() теперь сообщает, сколько файлов она помещает в массив, и сообщается, сколько места у нее доступно для работы.

Предварительное выделение строк на самом деле в основном впустую. Если бы это был мой код, я бы просто использовал calloc() для массива (нулевых) указателей, а затем использовал strdup() для копирования имен. И я, вероятно, увеличил бы массив указателей динамически по мере необходимости.

Смежные вопросы