我玩弄了C和不同的排序算法。我決定首先嚐試在不初始化的情況下聲明一些大小的自動數組(比如100),而不是生成一個隨機數組進行排序。我預計操作系統(我在Windows XP上)會將零置於其中,否則這可能是某些其他進程留下的數據。但事實證明,這種未初始化的數組中沒有零。所以第一個問題是:它可能是什麼數據,爲什麼不通過操作系統清理?難道它是「cmd」shell的垃圾嗎?我正在運行編譯器和程序?因爲我試過的排序算法沒有分配任何更多的內存,只是將所有內存排序,我認爲會有兩種可能性:(a)爲數組分配的內存區域將變爲在下一次運行中進行排序並保持這種狀態,或者(b)在下一次運行時,操作系統會給程序另外一部分內存,因此會導致另一個垃圾。但事實證明,它既不是。無論我分類多少次,內存都保持不變。所以,第二個問題是:我怎麼可能得到一些隨機的虛擬內存區域,對它進行排序,然後在下一次運行中,我會得到原始形式的相同區域?在Windows中分配的內存的內容
下面是代碼和我的步驟。
#include <stdio.h>
#define SIZE 100
void quick_sort(int *a, size_t size)
{
/* No comments here, everybody knows quicksort
and anyone will write it better! :) */
if(size <= 1) return;
int tmp, pivot;
int small_length, pivot_pos;
pivot_pos = size/2;
pivot = a[pivot_pos];
tmp = a[0];
a[0] = pivot;
a[pivot_pos] = tmp;
small_length = 0;
for(int i = 1; i < size; i++)
{
if(a[i] < pivot){
small_length++;
tmp = a[small_length];
a[small_length] = a[i];
a[i] = tmp;
}
}
a[0] = a[small_length];
a[small_length] = pivot;
quick_sort(a, small_length);
quick_sort(a + small_length + 1, size - small_length - 1);
}
int main(int argc, char *argv[])
{
int a[SIZE];
int i;
quick_sort(a, SIZE);
for(i = 0; i < SIZE; i++) {
printf("%d\n", a[i]);
}
return 0;
}
步驟I中使用:
- 編譯
quick_sort
呼叫評論,看到未排序未初始化數組:cc sort.c -Wall -std=c99 && a > unsorted1
(已編譯的可執行是a.exe
)。 - 取消註釋
quick_sort
來電查看排序結果:cc ... > sorted
。 - 再次評論該呼叫以再次查看未排序的數組:
cc ... > unsorted2
。 - 比較文件
unsorted1
和unsorted2
- 它們是相同的,全部100行。
我也嘗試啓動另一個「cmd」實例,並且數據是相同的。
更新
未排序的數據的一十六進制轉儲:
0000000 0000 0000 fd7c 0022 fd74 0022 fdd8 0022
0000020 0170 0000 1448 7c91 ffff ffff 1440 7c91
0000040 0000 0024 13d2 7c91 301c 0024 3008 0024
0000060 0010 0000 b988 7c97 0000 003e 0007 0000
0000100 fd24 0022 0000 0000 fe24 0022 e900 7c90
0000120 0040 0001 002e 0000 0000 003e eeeb 7c80
0000140 fe30 0022 e900 7c90 0040 7c91 ffff ffff
0000160 003d 0001 0002 0000 fd5c 0022 0000 0000
0000200 fe50 0022 0002 0000 0002 0000 ffff ffff
0000220 003d 7c91 c2de 77c1 0000 003e 0000 0000
0000240 c2e3 77c1 a122 0040 0000 0000 2bc4 003e
0000260 2070 77c0 ffff ffff 0000 003e 2bc0 003e
0000300 0004 0000 2373 0024 1660 0040 fea0 0022
0000320 c024 77c1 0000 003e 0000 0000 c02d 77c1
0000340 1660 0040 2373 0024 1dc0 0040 fec0 0022
0000360 c024 77c1 0000 003e 0000 0000 c02d 77c1
0000400 1dc0 0040 2373 0024 0000 0000 5c94 77c2
0000420 a52e 77c2 1ae8 77c5 fedc 0022 9d60 77c2
0000440 fe88 0022 4e2f 77c2 feec 0022 5c94 77c2
0000460 a52e 77c2 1ae8 77c5 fefc 0022 9d60 77c2
0000500 0008 0000 4e2f 77c2 4e29 77c2 ff3c 0022
0000520 2373 0024 0000 0000 1dc0 0040 fed4 0022
0000540 ff08 0022 ffe0 0022 5c94 77c2 2850 77c0
0000560 ffff ffff 4e29 77c2 4e42 77c2 1dc0 0040
0000600 ffa0 0022 1e1e 0040 1dc0 0040 0020 0000
爲了生產轉儲我不得不添加一個文件,的fopen(...),FCLOSE(...)到代碼,並改變了輸出。但是這些調用是在數組聲明之後進行的,所以仍然不確定這會如何影響數組的內容。
二,試圖將SIZE增加到10000,最後看到零。輸出是很多的零,最後是熟悉的垃圾。我不確定內存在哪個方向發展,我預計數據將停留在陣列的開始處......
向我們展示'unsorted1'的十六進制內容 - 最有可能的是分配器填充了類似0xDEADBEEF的東西(儘管我會懷疑更現代的版本......) –
操作系統不會給你的程序留下一塊內存一些其他的流程,這將是一個嚴重的信息泄露安全漏洞。內存只是在你的程序的C運行時庫啓動(全局構造函數,stdio初始化等)之前在調用'main()'之前執行的剩餘堆棧垃圾。 –