分段错误:在 Mac 上为 11,但在 Linux 上没有,同时在 C 中创建数组
Posted
技术标签:
【中文标题】分段错误:在 Mac 上为 11,但在 Linux 上没有,同时在 C 中创建数组【英文标题】:Segmentation fault: 11 on mac but not on linux while creating an array in C 【发布时间】:2019-01-14 20:03:08 【问题描述】:您好,我最近开始测试 QuickSort。我编写了一个程序,该程序使用用户输入的大小制作数组并用随机数填充它,然后使用快速排序对其进行排序。现在这是我的问题。在只有 4gb 内存的 linux 机器上,我可以在计算机无法使用之前制作最大 10^8 的数组。在我的 8gb 内存的 mac 上,我只能创建一个大小为 10^6 的数组。如果我尝试制作一个大小为 10^7 或更大的数组,则会出现分段错误。是操作系统的一些硬限制,可以更改吗? 这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int FindPivot(int i, int j);
void PrintTable(int* table, int size);
void NextThing(int* table, int size);
void QuickSort(int* table, int i, int j);
void RandomizeTable (int* table, int size)
int i;
for (i = 0; i < size; i++)
table[i] = -10000 + rand() % (10000+1-(-10000));
//printf("%d\t", table[i]);
printf("\n");
NextThing(table, size);
void NextThing(int* table, int size)
printf("Sorting the table...\n");
clock_t x = clock();
QuickSort(table, 0, size - 1);
clock_t y= clock();
printf("Time it took : %fs\n", ((double)(y - x))/CLOCKS_PER_SEC);
//Second sorting of the table, just to see how long does it take for quicksort to sort an already sorted table
printf("Sorting the table...\n");
clock_t x2 = clock();
QuickSort(table, 0, size - 1);
clock_t y2= clock();
printf("Time it took : %fs\n", ((double)(y2 - x2))/CLOCKS_PER_SEC);
exit(0);
void Swap(int* table, int i, int j)
int temp;
temp = table[i];
table[i] = table[j];
table[j] = temp;
int Partition(int* table, int i, int j)
int p, q, key;
p = FindPivot(i, j);
key = table[p];
Swap(table, i, p);
for (p = i, q = i + 1; q <= j; q++)
if (table[q] < key)
p++;
Swap(table, p, q);
Swap(table, i, p);
return p;
void QuickSort(int* table, int i, int j)
int p;
if (i < j)
p = Partition(table, i, j);
QuickSort(table, i, p - 1);
QuickSort(table, p + 1, j);
//QuickSort
void PrintTable(int* table, int size)
int i;
for (i = 0; i < size; i++)
printf("%d", table[i]);
printf("\n");
int FindPivot(int i, int j)
int pivot;
/*pivot = i + rand() % (j + 1 - i); */ //Method I randomizing pivot
pivot = (i + j) / 2; //Method II arithmetic avarage
return pivot;
int main ()
time_t t;
srand((unsigned) time(&t));
int n;
printf("Array size:");
scanf("%d", &n);
int tab[n]; //Here is where error occurs if array size is > 10^6
RandomizeTable(tab, n);
我几乎可以肯定,制作这样大小的数组是有问题的。我试过用 printf 调试代码。如果是在创建数组之前(在 main() 中)它会打印文本,如果我在之后放置它就不会打印它。
【问题讨论】:
您的符号time_t t; srand((unsigned) time(&t));
很冗长:您可以使用srand(time(0));
,或者,如果您坚持强制转换,则使用srand((unsigned)time(0));
— time()
函数对空指针作为其参数感到满意。
在大多数 Unix 系统上,您最多可以在堆栈上创建大约 8 MiB。不过,您通常应该在达到那个点之前很久就开始使用动态内存分配——开始担心是否在堆栈上创建了 1 MiB 的数据(如果只是因为在 Windows 上限制通常是 1 MiB——但也因为你可能没有想要在使用递归算法时吃掉所有的堆栈)。
在 linux 下,内存使用有一定的限制,可能是硬的或软的(取决于内核构建)。其中之一是“堆栈大小”。在 csh 中,您可以使用 limit
命令来检查和设置这些(如果它们是软的)。 mac 可能有类似的东西。
【参考方案1】:
假设您使用的是 C99,它可能是特定于实现的(但可能不是),其中任何对象的最大大小受 SIZE_MAX 限制,来自this post,这意味着最小 (理论上)可能小于 10^6 (1,000,000) 字节。
如果这是问题,您可以使用类似的方法进行检查
size_t max_size = (size_t)-1;
来自here。
否则,另一个帖子是你最好的选择——如果你不能在堆栈上实现它,使用malloc 可以在堆中分配它。
int *tab = malloc(n*sizeof(int));
这将在堆中分配 (n * sizeof(int in bytes)) 个字节,并且应该可以工作。
请注意,如果您以这种方式分配内存,则需要手动删除它,因此您应该在完成后调用free。
free(tab)
【讨论】:
动态分配就是答案。 在大多数系统上,SIZE_MAX
是 2³²-1(对于 32 位)和 2⁶⁴-1(对于 64 位)。虽然理论上SIZE_MAX
可能小到 65535 (2¹⁶-1),但在任何台式机或服务器系统上,这比实际情况更具理论性——如果限制那么小,您将使用 8 位微处理器。跨度>
无论 C 的版本如何,限制往往是相同的。但是,在 C90 中,SIZE_MAX
不是强制宏;它被添加到 C99 中(但也在 C11 和 C18 中)。以上是关于分段错误:在 Mac 上为 11,但在 Linux 上没有,同时在 C 中创建数组的主要内容,如果未能解决你的问题,请参考以下文章
C++ 服务器 Linux 机器上的分段错误 - 适用于 Mac
linux (g++) 上的分段错误,但 Mac OS 上没有。?
ejabber 的 erl 文件在 mac os 10.7.5 上运行时给出错误“分段错误:11”
Python 3.4在生成一些 - 但不是全部 - 具有分段错误11的Cartopy地图时崩溃