2015-03-09 3 views
0

Я столкнулся с какой-то странной проблемой, моя программа имеет segfault, когда я пытаюсь получить доступ к члену структуры, но адрес моей структуры не является NULL, и я никогда не освобождал эту структуру.Segfault при доступе к члену структуры

Адрес структуры - это что-то вроде «0x8000000000» или «0x2000000000».

Вот Б.Т. информации GDB:

Program received signal SIGSEGV, Segmentation fault. 
0x00000001000039cc in ft_sort_ascii (files=0x8000000000000) at srcs/sort/ascii.c:43 
43  while (i < files->len) 
(gdb) bt 
#0 0x00000001000039cc in ft_sort_ascii (files=0x8000000000000) at srcs/sort/ascii.c:43 
#1 0x0000000100003a3c in ft_sort_ascii (files=0x10080a400) at srcs/sort/ascii.c:50 
#2 0x0000000100003a3c in ft_sort_ascii (files=0x1001080d0) at srcs/sort/ascii.c:50 
#3 0x0000000100003a3c in ft_sort_ascii (files=0x100801800) at srcs/sort/ascii.c:50 
#4 0x0000000100003a3c in ft_sort_ascii (files=0x100801200) at srcs/sort/ascii.c:50 
#5 0x0000000100003a3c in ft_sort_ascii (files=0x100104c10) at srcs/sort/ascii.c:50 
#6 0x0000000100002137 in main (ac=1, av=0x7fff5fbff758) at srcs/main.c:26 

Отчет Valgrind:

==29835== 
==29835== HEAP SUMMARY: 
==29835==  in use at exit: 415,075 bytes in 11,152 blocks 
==29835== total heap usage: 17,711 allocs, 6,559 frees, 3,960,490 bytes allocated 
==29835== 
==29835== 112 bytes in 1 blocks are definitely lost in loss record 106 of 178 
==29835== at 0x10000CCA1: calloc (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so) 
==29835== by 0x1004ABC11: class_createInstance (in /usr/lib/libobjc.A.dylib) 
==29835== by 0x10010F920: _os_object_alloc_realized (in /usr/lib/system/libdispatch.dylib) 
==29835== by 0x1004650D5: _xpc_pipe_create (in /usr/lib/system/libxpc.dylib) 
==29835== by 0x100467655: xpc_pipe_create (in /usr/lib/system/libxpc.dylib) 
==29835== by 0x1002AE100: _od_xpc_pipe (in /usr/lib/system/libsystem_info.dylib) 
==29835== by 0x1002AE044: _od_running (in /usr/lib/system/libsystem_info.dylib) 
==29835== by 0x1002ADFD8: ds_user_byuid (in /usr/lib/system/libsystem_info.dylib) 
==29835== by 0x1002ADF46: search_item_bynumber (in /usr/lib/system/libsystem_info.dylib) 
==29835== by 0x1002ADE82: getpwuid (in /usr/lib/system/libsystem_info.dylib) 
==29835== by 0x1000029EB: ft_get_file_infos (in ./ft_ls) 
==29835== by 0x1000027B4: ft_set_infos_foreach (in ./ft_ls) 
==29835== 
==29835== 121 bytes in 1 blocks are definitely lost in loss record 107 of 178 
==29835== at 0x10000C59B: malloc (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so) 
==29835== by 0x100002F6B: ft_open_directories (in ./ft_ls) 
==29835== by 0x10000276E: ft_set_files (in ./ft_ls) 
==29835== by 0x100002120: main (in ./ft_ls) 
==29835== 
==29835== 405 bytes in 5 blocks are definitely lost in loss record 130 of 178 
==29835== at 0x10000C59B: malloc (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so) 
==29835== by 0x100002F6B: ft_open_directories (in ./ft_ls) 
==29835== by 0x10000276E: ft_set_files (in ./ft_ls) 
==29835== by 0x100003061: ft_open_directories (in ./ft_ls) 
==29835== by 0x10000276E: ft_set_files (in ./ft_ls) 
==29835== by 0x100002120: main (in ./ft_ls) 
==29835== 
==29835== 516 bytes in 20 blocks are definitely lost in loss record 133 of 178 
==29835== at 0x10000C59B: malloc (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so) 
==29835== by 0x100002F6B: ft_open_directories (in ./ft_ls) 
==29835== by 0x10000276E: ft_set_files (in ./ft_ls) 
==29835== by 0x100003061: ft_open_directories (in ./ft_ls) 
==29835== by 0x10000276E: ft_set_files (in ./ft_ls) 
==29835== by 0x100003061: ft_open_directories (in ./ft_ls) 
==29835== by 0x10000276E: ft_set_files (in ./ft_ls) 
==29835== by 0x100003061: ft_open_directories (in ./ft_ls) 
==29835== by 0x10000276E: ft_set_files (in ./ft_ls) 
==29835== by 0x100003061: ft_open_directories (in ./ft_ls) 
==29835== by 0x10000276E: ft_set_files (in ./ft_ls) 
==29835== by 0x100003061: ft_open_directories (in ./ft_ls) 
==29835== 
==29835== 2,523 bytes in 27 blocks are definitely lost in loss record 157 of 178 
==29835== at 0x10000C59B: malloc (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so) 
==29835== by 0x100002F6B: ft_open_directories (in ./ft_ls) 
==29835== by 0x10000276E: ft_set_files (in ./ft_ls) 
==29835== by 0x100003061: ft_open_directories (in ./ft_ls) 
==29835== by 0x10000276E: ft_set_files (in ./ft_ls) 
==29835== by 0x100003061: ft_open_directories (in ./ft_ls) 
==29835== by 0x10000276E: ft_set_files (in ./ft_ls) 
==29835== by 0x100002120: main (in ./ft_ls) 
==29835== 
==29835== 6,124 bytes in 140 blocks are definitely lost in loss record 165 of 178 
==29835== at 0x10000C59B: malloc (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so) 
==29835== by 0x100002F6B: ft_open_directories (in ./ft_ls) 
==29835== by 0x10000276E: ft_set_files (in ./ft_ls) 
==29835== by 0x100003061: ft_open_directories (in ./ft_ls) 
==29835== by 0x10000276E: ft_set_files (in ./ft_ls) 
==29835== by 0x100003061: ft_open_directories (in ./ft_ls) 
==29835== by 0x10000276E: ft_set_files (in ./ft_ls) 
==29835== by 0x100003061: ft_open_directories (in ./ft_ls) 
==29835== by 0x10000276E: ft_set_files (in ./ft_ls) 
==29835== by 0x100002120: main (in ./ft_ls) 
==29835== 
==29835== 6,493 bytes in 205 blocks are definitely lost in loss record 166 of 178 
==29835== at 0x10000C59B: malloc (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so) 
==29835== by 0x100002F6B: ft_open_directories (in ./ft_ls) 
==29835== by 0x10000276E: ft_set_files (in ./ft_ls) 
==29835== by 0x100003061: ft_open_directories (in ./ft_ls) 
==29835== by 0x10000276E: ft_set_files (in ./ft_ls) 
==29835== by 0x100003061: ft_open_directories (in ./ft_ls) 
==29835== by 0x10000276E: ft_set_files (in ./ft_ls) 
==29835== by 0x100003061: ft_open_directories (in ./ft_ls) 
==29835== by 0x10000276E: ft_set_files (in ./ft_ls) 
==29835== by 0x100003061: ft_open_directories (in ./ft_ls) 
==29835== by 0x10000276E: ft_set_files (in ./ft_ls) 
==29835== by 0x100002120: main (in ./ft_ls) 
==29835== 
==29835== 341,832 (104 direct, 341,728 indirect) bytes in 1 blocks are definitely lost in loss record 178 of 178 
==29835== at 0x10000C59B: malloc (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so) 
==29835== by 0x100002474: ft_set_files (in ./ft_ls) 
==29835== by 0x100002120: main (in ./ft_ls) 
==29835== 
==29835== LEAK SUMMARY: 
==29835== definitely lost: 16,398 bytes in 400 blocks 
==29835== indirectly lost: 341,728 bytes in 10,269 blocks 
==29835==  possibly lost: 0 bytes in 0 blocks 
==29835== still reachable: 22,201 bytes in 62 blocks 
==29835==   suppressed: 34,748 bytes in 421 blocks 
==29835== Reachable blocks (those to which a pointer was found) are not shown. 
==29835== To see them, rerun with: --leak-check=full --show-leak-kinds=all 
==29835== 
==29835== For counts of detected and suppressed errors, rerun with: -v 
==29835== ERROR SUMMARY: 1243 errors from 14 contexts (suppressed: 21 from 21) 

Кажется, у меня есть много ошибок/утечки, я не освободить свою память, что я использовал один раз (все мои t_files) потому что они будут освобождены в конце программы.

И вот мой код:

static void  ft_swap_files(t_files *files, size_t *i) 
{ 
    size_t j; 
    t_files tmp; 

    j = *i + 1; 
    while (j < files->len) 
    { 
     if (files[j].error < 0) 
     { 
      if (ft_strcmp(files[*i].name, files[j].name) > 0) 
      { 
       tmp = files[*i]; 
       files[*i] = files[j]; 
       files[j] = tmp; 
       *i = -1; 
       return ; 
      } 
     } 
     j++; 
    } 
} 

void   ft_sort_ascii(t_files *files) 
{ 
    size_t i; 

    i = 0; 
    while (i < files->len) 
    { 
     if (files[i].error < 0) 
     { 
      ft_swap_files(files, &i); 
      if (files[i].files != NULL) 
      { 
       ft_sort_ascii(files[i].files); 
      } 
     } 
     i++; 
    } 
} 

Моя t_files структура:

typedef struct  s_files 
{ 
    size_t   len; 
    t_bool   hidden; 
    int    error; 
    char   *path; 
    char   *name; 
    char   *sym_name; 
    char   *rights; 
    char   *uid; 
    char   *gid; 
    char   *time; 
    int    nlink_max; 
    int    size_max; 

    /* 
    ** from stat 
    */ 
    int    type; 
    int    nlink; 
    int    size; 

    t_bool   rd; 
    struct s_files *files; 
}     t_files; 

Эта ошибка возникает после нескольких рекурсивных вызовов. «файлы [i] .files» инициализируются в NULL в другом файле и при необходимости являются malloc.

Рекурсивные вызовы могут вызывать проблемы?

Спасибо-х;)

+3

Это пахнет повреждением памяти (долго?) Перед сбоем. Попробуйте запустить вашу программу с помощью средства проверки памяти, такого как Valgrind (http://valgrind.org). – alk

+1

Адрес памяти не должен быть NULL, чтобы вызвать нарушение памяти при доступе. Достаточно того, что он просто выходит из доступного диапазона (если есть защита памяти) или переписывает некоторые важные данные/код. Рекурсия может привести к переполнению стека, поэтому попытайтесь сузить проблему. –

+3

И почему у вас заголовок «* Доступ к указателю NULL *», когда вы явно не обращаетесь к указателю NULL («* address is not NULL *)»? – alk

ответ

1

У вас есть потенциальный доступ массив сгущенного в ft_sort_ascii(). В ft_swap_files() у вас есть код:

 *i = -1; 
     return ; 
} 

, который возвращается к следующему коду в ft_sort_ascii():

ft_swap_files(files, &i); 

if (files[i].files != NULL) // Underflow here if i == -1 
{ 
    ft_sort_ascii(files[i].files); // and here if it gets this far 
} 

который недостаточное в files[] массиве. Вам нужно будет проверить, действительно ли i является действительным индексом перед выполнением любого доступа к нему массива.

+0

i является допустимым индексом, потому что на ft_swap_files возврат, я увеличивается, чтобы наконец быть установлен в 0 -> если (файлы [я] .error <0) \t \t { \t \t \t ft_swap_files (файлы, &i); \t \t \t если (файлы [я] .files! = NULL) \t \t \t { \t \t \t \t ft_sort_ascii (файлы [I] .files); \t \t \t} \t \t} \t \t я ++; – Ziad

+0

@Zlad: но оператор 'if' сразу после того, как' ft_swap_files() 'обращается к файлам' [i] 'до' i' увеличивается. –

+0

Спасибо @MichaelBurr, вы решили мою проблему <3 – Ziad