2015-06-05 32 views
0

對於任務,我必須訂購學生列表。每一個都由一個數字(15號字符串),他父親的姓氏(字符串20),他母親的姓氏(字符串20)和他的名字(字符串20也)表示。C - 輸入大的內存泄漏

我做了一個程序,從一個文件生成的學生列表並命令它(我使用合併排序來這樣做)。

當我在少數學生(< 10000)上運行該程序時,一切都很好(沒有內存泄漏或根據valgrind的任何內容)。但是,只要我嘗試在較大的(超過100 000)上使用它,我會得到一個分段錯誤11.我用Valgrind進行了調查,它說錯誤來自strcy或strcasecmp函數,並呈現:

==2433== Invalid write of size 8 
==2433== at 0x4019BD: merge (sort.c:59) 
==2433== by 0x40173B: sortBeginEnd (sort.c:38) 
==2433== by 0x4014B0: sortWithoutInterval (sort.c:9) 
==2433== by 0x401EE0: firstSort (sort.c:166) 
==2433== by 0x4009EB: main (main.c:44) 
==2433== Address 0xffe79ac88 is on thread 1's stack 
==2433== 
==2433== 
==2433== Process terminating with default action of signal 11 (SIGSEGV) 
==2433== Access not within mapped region at address 0xFFE79AC88 
==2433== at 0x4019BD: merge (sort.c:59) 
==2433== If you believe this happened as a result of a stack 
==2433== overflow in your program's main thread (unlikely but 
==2433== possible), you can try to increase the size of the 
==2433== main thread stack using the --main-stacksize= flag. 
==2433== The main thread stack size used in this run was 8388608. 
==2433== 
==2433== Process terminating with default action of signal 11 (SIGSEGV) 
==2433== Access not within mapped region at address 0xFFE79AC81 
==2433== at 0x4A256B0: _vgnU_freeres (in /usr/lib/valgrind/vgpreload_core-amd64-linux.so) 
==2433== If you believe this happened as a result of a stack 
==2433== overflow in your program's main thread (unlikely but 
==2433== possible), you can try to increase the size of the 
==2433== main thread stack using the --main-stacksize= flag. 
==2433== The main thread stack size used in this run was 8388608. 
==2433== 
==2433== HEAP SUMMARY: 
==2433==  in use at exit: 12,800,101 bytes in 500,007 blocks 
==2433== total heap usage: 500,008 allocs, 1 frees, 12,800,669 bytes allocated 
==2433== 
==2433== LEAK SUMMARY: 
==2433== definitely lost: 0 bytes in 0 blocks 
==2433== indirectly lost: 0 bytes in 0 blocks 
==2433==  possibly lost: 0 bytes in 0 blocks 
==2433== still reachable: 12,800,101 bytes in 500,007 blocks 
==2433==   suppressed: 0 bytes in 0 blocks 
==2433== Rerun with --leak-check=full to see details of leaked memory 
==2433== 
==2433== For counts of detected and suppressed errors, rerun with: -v 
==2433== ERROR SUMMARY: 7452721 errors from 31 contexts (suppressed: 0 from 0) 

可能的錯誤是我用了太多的內存(每個學生代表79個字符= 316個字節,我有100 000人,因此是31個600 000字節,如果我是正確的)?

PS:我不是真正熟悉棧和堆的概念

編輯:

「一切都很好」 的valgrind報告:

==2454== 
==2454== HEAP SUMMARY: 
==2454==  in use at exit: 0 bytes in 0 blocks 
==2454== total heap usage: 50,008 allocs, 50,008 frees, 1,280,669 bytes allocated 
==2454== 
==2454== All heap blocks were freed -- no leaks are possible 
==2454== 
==2454== For counts of detected and suppressed errors, rerun with: -v 
==2454== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) 

EDIT2:

的代碼是here如果你想檢查它。

編輯LAST:

我終於找到了解決辦法感謝@倫丁的答案。問題是我沒有使用malloc來爲mergeSort的合併部分分配臨時數組。

我會調查一下堆/棧的問題,以充分理解問題。

+2

我想,首先你應該爲'segfault'煩惱。檢查並向我們顯示'sort.c:59' –

+0

通過valgrind運行您的「一切都很好」也是值得你花時間的。它可能不像你想象的那樣「好」。 *發佈代碼*。 – WhozCraig

+0

請給我們展示一些代碼! –

回答

3

你甚至沒有提到這是用於哪個系統。由於Valgrind我假設Linux。你沒有提到你分配變量的位置。顯然,Valgrid在那裏只報告12.8kb,因此不在堆上。

如果我沒有記錯(而且我對Linux知之甚少)進程的堆棧大小大約爲8Mb。

316 * 10000 = 3.16 Mb. 
316 * 100000 = 31.60 Mb. 

合格的答案:如果您在任何其他方式比使用malloc分配的變量,那麼棧溢出,所描述的問題的根源。

每當在程序中使用大量內存時,您必須在堆上動態分配它們。

+0

是的,我使用的是Linux。我使用malloc分配。已添加代碼。 – M0rkHaV

+0

我想我發現解決方案感謝您的評論。在進行合併時,我不使用malloc來構建臨時數組。我會嘗試用malloc分配它們。 – M0rkHaV

1

堆棧是您的函數保存其本地/臨時數據(參數和局部變量)的地方。它被組織爲一堆文件,所以當你調用一個函數時,這些參數被放到堆棧中,並且當函數完成時,除了結果之外的所有內容都會從堆棧中被丟棄。通常堆棧的大小是有限的。

堆是內存,您的分配數據保存在其中(f.e. malloc())。你可以有不同的堆(對於你的應用程序,對於每個進程和系統範圍)