2013-08-03 42 views
8

Sửa nguồn đầy đủ ở đây:malloc() bị treo, nói hỏng danh sách đúp liên kết

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

Calling chương trình tại đây:

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

Tôi đã có một tương đối phân bổ bộ nhớ đơn giản không thành công. Ứng dụng không đặc biệt phức tạp mặc dù nó phân bổ bộ nhớ ở một vài nơi. Đó là C, không phải C++. Tôi đang tích cực đây là sự cố phân bổ bộ nhớ, không phải là giải phóng bộ nhớ.

Dưới đây là các mã:

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

Khi thực hiện, tôi nhận được:

: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 
  • mã biên dịch mà không vấn đề.
  • Khi tôi chạy nó "độc lập", nó gặp sự cố với lỗi ở trên. Tôi thấy :2 nhưng tôi không thấy :3, cho tôi biết đó là lỗi trong malloc. (Tôi hy vọng tôi sai.)
  • Khi tôi chạy cùng một nhị phân qua valgrind, nó hoạt động như mong đợi.
  • Dường như đây không phải là vấn đề với tuyên bố biến số o->data, là char*. Nếu tôi khai báo char* A; A = thay vì o->data = nó vẫn bị treo.

Tôi đánh giá cao mọi ý tưởng về cách khắc phục sự cố/lý do điều này xảy ra.

Cảm ơn!

+1

là '* O' đối tượng được phân bổ? – ouah

+4

Bạn sẽ cần phải cung cấp một SSCCE: http://sscce.org/ –

+1

Cần xem một ví dụ đầy đủ, có thể biên dịch được như những người khác đã nói, nhưng trong thời gian chờ đợi, không đưa trở lại từ 'malloc()', và không sử dụng 'sizeof (char)' vì nó luôn là '1'. –

Trả lời

-1

EDIT: Vì chúng tôi hầu như không biết cấu trúc của bạn trông như thế nào và kiểu dữ liệu o->data nên, chúng tôi chỉ có thể xác định những gì bạn đang cố gắng làm.

Vui lòng chỉ định định nghĩa cấu trúc o, để chúng tôi có thể trợ giúp.

+1

Hầu như chắc chắn sai.Nếu bạn đã phân bổ các con trỏ 'char', bạn sẽ lưu trữ kết quả trong một' char ** ', không phải là một' char * ', mặc dù đã thừa nhận mà không nhìn thấy một ví dụ đầy đủ thì không thể biết loại' o-> data' là, nhưng mã của anh ta ít nhất là phù hợp, và của bạn thì không. –

+0

Tôi phải nói rằng tôi dường như đã cẩu thả khi đọc. Lỗi của tôi. Loại thuộc tính 'o-> data' nên được đưa ra để đề xuất đầy đủ những gì anh ta đang cố gắng làm. Tôi đoán là anh ta đang cố gắng để lưu một chuỗi. Nhưng nhìn vào mã của anh ta một lần nữa sẽ gợi ý anh ta đang cố gắng làm điều gì đó khác ... Tôi sẽ sửa bài của tôi. – DaMachk

+2

Câu trả lời được cập nhật sẽ tốt hơn làm nhận xét. Bạn sẽ có thể xóa câu trả lời của riêng bạn nếu bạn muốn loại bỏ các downvotes ở đây – simonc

13

Vì vậy, tôi nghĩ tôi đã tìm thấy nó. Chúng ta có thể cần phải nộp điều này dưới "Sean cần phải học các kỹ năng cơ bản của Valgrind." Đây là cách tôi giải quyết nó cho bất kỳ nhà quan sát tương lai nào.

  1. OK, chúng tôi đang xử lý một lỗi thực sự lạ do thư viện đã thử và thử nghiệm , vì vậy nó phải là điều gì đó cụ thể cho thiết lập của tôi. Thuật toán giống nhau, do đó, nó phải là dữ liệu.
  2. Việc triển khai bộ nhớ động có cấu trúc dữ liệu cơ bản để theo dõi bộ nhớ được phân bổ , điều này xảy ra là danh sách được liên kết kép - do đó là thông báo.
  3. Vì vậy, phải có hoạt động bộ nhớ ở đâu đó mà làm hỏng cấu trúc dữ liệu này trong một cách tinh tế.
  4. Được rồi, chúng tôi có những công cụ gì theo ý của mình? Valgrind được đánh giá cao, hãy thử đó. Lạ thật, nó hoạt động ở Valgrind. Hmm.
  5. Thực sự đọc những gì Valgrind đang nói với bạn. (Đây là nơi tôi không làm phần của mình.) gắn cờ cho bạn với các lỗi như "Viết kích thước không hợp lệ 1" không hợp lệ cùng với dấu vết của các nhãn/biểu tượng khác nhau nơi hiển thị này. Tìm các lỗi có thể xảy ra và điều chỉnh theo yêu cầu .
  6. Trong trường hợp này, nó chỉ tôi đến một yêu cầu memcpy() trong chức năng hashtable_put của hashtable.c. Các gợi ý tinh tế là tôi đã vượt qua đối số đầu tiên để memcpy bằng cách sử dụng địa chỉ của nhà điều hành &, gây ra tham nhũng.
  7. Khi tôi sửa lỗi đó, Valgrind không còn bị khiếu nại.

Các đạo đức của câu chuyện:

  • Đừng bỏ qua thông tin phản hồi từ các công cụ. Không có tin tức nào là một tin tốt lành, vì vậy nếu Valgrind phun ra nhiều thông tin thì đó là khả năng gia tăng của một vấn đề.
  • Lỗi phân bổ bộ nhớ động là tinh tế (động theo nghĩa thực sự của từ) và có thể bị ảnh hưởng bởi nhiều biến. Valgrind đặt mọi thứ vào giữa chương trình và thư viện bộ nhớ của bạn để nó biết những gì đang xảy ra, vì vậy tôi nghĩ rằng những hoạt động này bị ảnh hưởng bởi hoạt động của chương trình .

Các cam kết rằng cho đến nay đã khắc phục sự cố:

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

+0

Công việc tốt sửa chữa vấn đề của riêng bạn. Tôi cũng đã biên dịch và chạy mã của bạn một cách thành công (với một vài sửa lỗi để loại bỏ các cảnh báo) với các nhận xét xung quanh hàm 'main()' của bạn, do đó sẽ là một đầu mối khác mà vấn đề ở nơi khác. –

+0

Xin chào, tôi cũng đã gặp sự cố mà bạn đã chỉ vào mã của riêng tôi. Tôi không thể bắt được giải pháp của bạn mặc dù ... Tôi đã đi qua mã thee và sau điểm là không rõ ràng: mối quan hệ giữa gọi memcopy() và malloc() là gì? Tôi thấy hoàn toàn không có mối quan hệ. Tôi chắc chắn bỏ lỡ một cái gì đó rất tinh tế. –

Các vấn đề liên quan