2013-08-03 3 views
8

Редактировать Полный источник здесь:таНос() падает, говоря поврежденную двойной связанный список

http://code.seanwoods.com/reynard.fossil.cgi/artifact/0cc9cbfbe021c2ba86dcb4d0cf6ada52f0a80063

Вызов программы здесь:

http://code.seanwoods.com/reynard.fossil.cgi/artifact/891405e62c95349aaf461dfb8ba82259f77fac9b

У меня относительно простое распределение памяти, которое не работает. Приложение не особенно сложно, хотя оно выделяет память в нескольких местах. Это C, а не C++. Я уверен, что это проблема , выделяющая память, а не освобождение память.

Вот код:

printf(":2 %d %d\n", initial_len, initial_len * sizeof(char)); 
o->data = (char*) malloc(initial_len * sizeof(char)); 
printf(":3 \n"); 

После выполнения, я получаю:

:1 
:2 1024 1024 
*** glibc detected *** ./menv: corrupted double-linked list: 0x0000000001d14400 *** 
======= Backtrace: ========= 
/lib/x86_64-linux-gnu/libc.so.6(+0x76d76)[0x7f680cfc4d76] 
/lib/x86_64-linux-gnu/libc.so.6(+0x771ed)[0x7f680cfc51ed] 
/lib/x86_64-linux-gnu/libc.so.6(+0x794d4)[0x7f680cfc74d4] 
/lib/x86_64-linux-gnu/libc.so.6(__libc_malloc+0x70)[0x7f680cfc9b90] 
./menv[0x403971] 
./menv[0x40391d] 
./menv[0x4030ec] 
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd)[0x7f680cf6cead] 
./menv[0x401369] 
======= Memory map: ======== 
00400000-00405000 r-xp 00000000 08:03 2621441       /home/swoods/code/reynard/modules/stdlib/menv 
00605000-00606000 rw-p 00005000 08:03 2621441       /home/swoods/code/reynard/modules/stdlib/menv 
00606000-00706000 rw-p 00000000 00:00 0 
01cfd000-01d3d000 rw-p 00000000 00:00 0         [heap] 
7f6808000000-7f6808021000 rw-p 00000000 00:00 0 
7f6808021000-7f680c000000 ---p 00000000 00:00 0 
7f680cd38000-7f680cd4d000 r-xp 00000000 08:05 10354962     /lib/x86_64-linux-gnu/libgcc_s.so.1 
7f680cd4d000-7f680cf4d000 ---p 00015000 08:05 10354962     /lib/x86_64-linux-gnu/libgcc_s.so.1 
7f680cf4d000-7f680cf4e000 rw-p 00015000 08:05 10354962     /lib/x86_64-linux-gnu/libgcc_s.so.1 
7f680cf4e000-7f680d0ce000 r-xp 00000000 08:05 10354980     /lib/x86_64-linux-gnu/libc-2.13.so 
7f680d0ce000-7f680d2ce000 ---p 00180000 08:05 10354980     /lib/x86_64-linux-gnu/libc-2.13.so 
7f680d2ce000-7f680d2d2000 r--p 00180000 08:05 10354980     /lib/x86_64-linux-gnu/libc-2.13.so 
7f680d2d2000-7f680d2d3000 rw-p 00184000 08:05 10354980     /lib/x86_64-linux-gnu/libc-2.13.so 
7f680d2d3000-7f680d2d8000 rw-p 00000000 00:00 0 
7f680d2d8000-7f680d2da000 r-xp 00000000 08:05 10354973     /lib/x86_64-linux-gnu/libdl-2.13.so 
7f680d2da000-7f680d4da000 ---p 00002000 08:05 10354973     /lib/x86_64-linux-gnu/libdl-2.13.so 
7f680d4da000-7f680d4db000 r--p 00002000 08:05 10354973     /lib/x86_64-linux-gnu/libdl-2.13.so 
7f680d4db000-7f680d4dc000 rw-p 00003000 08:05 10354973     /lib/x86_64-linux-gnu/libdl-2.13.so 
7f680d4dc000-7f680d4fc000 r-xp 00000000 08:05 10354984     /lib/x86_64-linux-gnu/ld-2.13.so 
7f680d6df000-7f680d6e2000 rw-p 00000000 00:00 0 
7f680d6f8000-7f680d6fb000 rw-p 00000000 00:00 0 
7f680d6fb000-7f680d6fc000 r--p 0001f000 08:05 10354984     /lib/x86_64-linux-gnu/ld-2.13.so 
7f680d6fc000-7f680d6fd000 rw-p 00020000 08:05 10354984     /lib/x86_64-linux-gnu/ld-2.13.so 
7f680d6fd000-7f680d6fe000 rw-p 00000000 00:00 0 
7ffff3bd6000-7ffff3bf7000 rw-p 00000000 00:00 0       [stack] 
7ffff3bff000-7ffff3c00000 r-xp 00000000 00:00 0       [vdso] 
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0     [vsyscall] 
Aborted 
  • Код компилируется без проблем.
  • Когда я запускаю его «автономно», он падает с ошибкой выше. Я вижу :2, но я не вижу :3, что говорит мне об ошибке в пределах malloc. (Надеюсь, я ошибаюсь.)
  • Когда я запускаю тот же двоичный код через valgrind, он работает так, как ожидалось.
  • Это не является проблемой с объявлением переменной o->data, которое является char*. Если я объявлю char* A; A = вместо o->data =, он по-прежнему падает.

Я бы очень признателен за любые идеи относительно того, как устранить неполадки/почему это происходит.

Спасибо!

+1

ли '* O' объект, выделенный? – ouah

+4

Вам нужно будет предоставить SSCCE: http://sscce.org/ –

+1

Нужно увидеть полный, компилируемый пример, как говорили другие, но в то же время не бросайте возврат из 'malloc()', и не используйте 'sizeof (char)', поскольку он всегда '1'. –

ответ

-1

EDIT: Как мы почти не знаем, как выглядит ваша структура o и какой тип данных o->data должен быть, мы можем только рассказать о том, что вы пытаетесь сделать.

Просьба указать определение структуры o, поэтому мы можем помочь.

+1

Почти наверняка неправильно.Если вы выделяете указатели «char», вы должны сохранять результат в 'char **', а не 'char *', хотя, по общему признанию, не имея полного примера, невозможно определить тип 'o-> data' есть, но его код, по крайней мере, непротиворечивый, а ваш - нет. –

+0

Должен сказать, что я, по-видимому, небрежно читал. Виноват. Тип свойства 'o-> data' должен быть дан, чтобы полностью рекомендовать то, что он пытается сделать. Я предполагал, что он пытается сохранить строку. Но, глядя на его код снова, он предположил бы, что он пытался сделать что-то еще ... Я отредактирую свой пост. – DaMachk

+2

Обновленный ответ будет лучше в качестве комментария. Вы должны иметь возможность удалить свои собственные ответы, если вы хотите удалить downvotes здесь – simonc

13

Итак, я думаю, что нашел. Возможно, нам понадобится подать это в разделе «Шон должен изучить базовые навыки Вальгринда». Вот как я решил это для будущих наблюдателей.

  1. Хорошо, мы имеем дело с очень странной ошибкой, брошенной испытанной функции библиотеки , поэтому оно должно быть что-то конкретное для моей установки. Алгоритм тот же, , поэтому он должен быть данных.
  2. Реализация динамической памяти имеет базовую структуру данных для отслеживания выделенной памяти , которая является двусвязным списком - таким образом, сообщение.
  3. Итак, должна быть операция с памятью где-то, что развращает эту структуру данных в тонким способом.
  4. Хорошо, какие инструменты у нас есть в нашем распоряжении? Valgrind высоко оценили, давайте попробуем что. Странно, он работает в Вальгринде. Хм.
  5. На самом деле читайте, что вам говорит Вальгринд. (Это то место, где я не выполнял свою роль.) Это содержит флаги с ошибками, такими как «Неверная запись размера 1» вместе со следом различных ярлыков/символов, где это отображается. Посмотрите на возможные ошибки и настройте как .
  6. В этом случае он указывал на вызов memcpy() в функции hashtable_put функции hashtable.c. Тонкий намек заключается в том, что я передавал первый аргумент memcpy, используя адрес-оператора &, что вызвало повреждение.
  7. Когда я исправил это, Valgrind больше не жаловался.

Мораль истории:

  • Не игнорировать обратную связь от инструментов. Нет новостей [обычно] хорошие новости, поэтому, если Valgrind выплевывает много информации, это увеличивает вероятность возникновения проблемы.
  • Ошибки динамического выделения памяти являются тонкими (динамическими в истинном смысле слова) и могут быть затронуты многими переменными. Valgrind помещает вещи в середину вашей программы и библиотеки памяти, чтобы она знала, что происходит, поэтому я думаю, что это повлияло на работу программы как-то.

коммит, который до сих пор исправили проблему:

http://code.seanwoods.com/reynard.fossil.cgi/ci/bd6a5a23c1?sbs=0

+0

Хорошая работа, фиксирующая вашу собственную проблему. Я также успешно скомпилировал и запустил ваш код (с несколькими исправлениями, чтобы избавиться от предупреждений) с комментариями вокруг вашей функции 'main()', поэтому это было бы еще одним ключом к тому, что проблема была в другом месте. –

+0

Привет, я тоже столкнулся с проблемой, которую вы указали в моем собственном коде. Я не мог поймать ваше решение, хотя ... Я прошел через ваш код, и следующая точка неясна: Какова связь между вызовами memcopy() и malloc()? Я не вижу абсолютно никакого отношения. Я, конечно, пропускаю что-то очень тонкое. –

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