- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我编写了一个 C 程序来使用动态分配的数组对整数进行合并排序(递归)。它适用于最多 100k 个整数,但当我输入 100 万个整数时,它会抛出 Segmentation fault (core dumped)
错误。
为什么要这样做?我的 16GB RAM 不够好吗?如果我不使用动态分配的数组,它是否能够对更大数量的整数进行排序?
动态分配究竟是如何工作的?根据我的理解,当动态变量或动态数组中的元素被声明时,内存的一部分(RAM?)被搁置并设置为严格存储声明的变量,直到内存被释放。
当我的程序试图留出内存来容纳一百万个整数时,它是否会因为没有足够的可用内存而失败?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define BIL 1E9
//struct Sort allows dynamic allocation of the array used in insertion sort.
typedef struct {
int *arr; //pointer to the dynamic array
size_t used; //stores number of 'used' elements in the array
size_t size; //stores number of total elements
} Sort;
//function prototypes to interact with the dynamic array
void freeSort(Sort *);
void initSort(Sort *, size_t);
void inSort(Sort *, int);
//prototypes for the Merge Sort
void mergeSort(Sort *, int, int, int []);
void merge(Sort *, int, int, int, int []);
void copyArray(int [], int, int, Sort *);
int main(){
//declare Sort variable 'magic' to perform the magical insertion sort on the dynamic array.
Sort magic;
initSort(&magic, 10); //initialize magic with 10 elements
//variables to allow the program to function
int intin;
char filename[15];
//tosort is the file to sort.
//sorted is the output file after sort.
FILE *tosort, *sorted;
//necessary variables to measure time
struct timespec start, finish;
//prompt user for file name.
printf("Enter the name of file with a list of integers to sort: ");
scanf("%s", filename);
tosort = fopen(filename, "r"); //read 'tosort' file
//write the 'sorted' file to 'filename.sorted'
sorted = fopen(strcat(filename, ".sorted"), "w");
//while loop stores every integer in the dynamically allocated magic array from tosort file.
while (!feof(tosort)) {
fscanf(tosort, "%d", &intin);
inSort(&magic, intin);
}
//n stores number of integers to sort
int n = magic.used;
//temporary array for use with the merge sort
int sortedArray [n];
//measure time
clock_gettime(CLOCK_REALTIME, &start); //start
//Merge Sort
mergeSort(&magic, 0, n, sortedArray);
clock_gettime(CLOCK_REALTIME, &finish); //finish
//calculate the elapsed time in nanoseconds.
double elapsed = (finish.tv_sec-start.tv_sec)+(finish.tv_nsec-start.tv_nsec)/BIL;
printf("Merge Sort took %lf seconds\n", elapsed);
//write the sorted array to 'sorted' ('filename'.sorted)
for (int i = 0; i < n; i++) {
fprintf(sorted, "%d\n", magic.arr[i]);
}
//free up the allocated memory for the Sort array and close the files.
freeSort(&magic);
fclose(tosort);
fclose(sorted);
return 0;
}
//initialize the dynamic array
void initSort(Sort *dynA, size_t initSize) {
dynA->arr = (int *)malloc(initSize * sizeof(int));
dynA->used = 0;
dynA->size = initSize;
}
//add values to the elements of the dynamic array
void inSort(Sort *dynA, int val) {
//if the array size is not big enough to fit new values, allocate 100 more elements.
if (dynA->used == dynA->size) {
dynA->size += 100;
dynA->arr = (int *)realloc(dynA->arr, dynA->size * sizeof(int));
}
//'used' holds the number of used elements with values in the array.
dynA->arr[dynA->used++] = val;
}
//free allocated memory for the dynamic array
void freeSort(Sort *dynA) {
free(dynA->arr);
dynA->arr = NULL;
dynA->used = dynA->size = 0;
}
//split the array until size is 1
void mergeSort(Sort *dynA, int begin, int end, int tempA [])
{
//if size is 1, done splitting.
if(end-begin < 2)
return;
// recursively split the array
int mid = (end+begin)/2; // mid = middle point
mergeSort(dynA, begin, mid, tempA); // mergeSort left half
mergeSort(dynA, mid, end, tempA); // mergeSort right half
merge(dynA, begin, mid, end, tempA); // merge the two halves
copyArray(tempA, begin, end, dynA); // copy the merged array to dynA
}
//merge the two arrays
void merge (Sort *dynA, int begin, int mid, int end, int tempA [])
{
int i = begin; int j = mid;
//from begin to end, compare the values of the two arrays
for (int k = begin; k < end; k++)
// store the smaller value into tempA[k]
if (j >= end || (i < mid && dynA->arr[i] <= dynA->arr[j]))
tempA[k] = dynA->arr[i++];
else tempA[k] = dynA->arr[j++];
}
//copy the contents of the temporary array to the dynamic array
void copyArray(int tempA[], int begin, int end, Sort *dynA){
for(int k = begin; k < end; k++)
dynA->arr[k] = tempA[k];
}
当我输入一百万个整数进行排序时,Cygwin64 和 CommandPrompt 给出相同的错误。
最佳答案
您的错误是您正在使用基于大 堆栈的 VLA sortedArray
。对于 1,000,000 个值,您的数组为 4MB,由于数组超出预设的堆栈大小限制,您会因堆栈溢出而出现段错误。
例如,在 linux 下,堆栈限制约为 8MB [在我的系统上,我不得不将数组计数增加到 3,000,000 以重现段错误]
改变:
//temporary array for use with the merge sort
int sortedArray [n];
进入:
//temporary array for use with the merge sort
int *sortedArray = malloc(sizeof(int) * n);
可选地,如果您愿意,可以在 main
的底部添加一个 free(sortedArray)
以保持整洁。
此外,您可以使用 limit
shell 命令查看 stacksize
参数设置的值。因此,解决此问题的另一种方法是使用命令来增加限制。但是,我不推荐这样做,因为与简单地使用 malloc
相比,它是一种不太通用且更脆弱的解决方案。
关于调试技巧...
为了找到您的问题,我做了以下工作:
使用调试信息编译程序:gcc -o blah -g blah.c
使用 gdb ./blah
调用调试器
使用run
运行程序[在调试器内部]
我得到了下面的段错误信息:
Starting program: ...
Enter the name of file with a list of integers to sort: input2
Program received signal SIGSEGV, Segmentation fault.
0x00000000004009d1 in main () at blah.c:64
64 clock_gettime(CLOCK_REALTIME, &start); //start
clock_gettime
出错没有多大意义,所以我查看了它上面的行:
int sortedArray [n];
关于c - 使用动态分配的数组递归合并排序大量整数会引发错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39883455/
我正在使用 SharePoint Online 并使用 Windows Azure 托管访问 SPO 的进程。 我们已将启动任务添加到 Azure 角色以安装 http://www.microsoft
我有一个函数,它获取包含时间的源文件(csv 文件),读取它,然后按顺序对行进行排序并将它们写入目标文件中。但是,如果源 csv 文件不存在,我需要引发 FileNotFoundError。我之前曾引
我试图在目录不存在时引发错误,然后再打开该目录中的文件。根据this response我应该为我的问题使用最具体的异常构造函数,我认为它是 NotADirectoryError。但是运行下面的代码我得
在编码/开发生命的一天或另一天,我们确实遇到了这个特殊的情况,这是最常见的异常(exception)之一。我的问题是关于的而不是。为什么(我知道当我们尝试访问实际上指向null的引用变量的属性时会引发
我想知道在 python 中是否可以在一个 except block 中引发异常并在稍后的 except block 中捕获它。我相信其他一些语言默认会这样做。 这是它的样子" try: som
我有以下代码: br = mechanize.Browser() br._factory.is_html = True br.form = mechanize._form.ParseString(''
我刚刚发现,如果您有一个引发 TOO_MANY_ROWS 异常的 SELECT INTO,该变量仍会从查询检索到的第一条记录中分配值。这是预期的行为吗? 这是我的例子: for co in my_cu
当 SSH 显示 WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! 我知道当您重新安装远程服务器时会发生这种情况,但我尝试列出 其他原因 . 我知道如何
我有一个枚举和一个 EnumMap . 我将 map 放入一个类中以隐藏“字节”值。所以我有一个set(Parameter, int)和set(Parameter, boolean)方法。 publi
在什么情况下会redis-py引发以下 AttributeError 异常? redis-py 不是设计来引发仅基于 redis.exceptions.RedisError 的异常吗? 什么是合理的处
可悲的是,对此异常的引用通常具有异国情调,并且可能发生在您例如通过 Assembly.GetTypes() 枚举类型- 举个例子,它发生在我们的一个部署上,但同一组程序集在集成服务器上运行良好。 为了
我正在为 Android 下的特定平板电脑克隆一个存储库并获取源代码,我必须执行一个 python 脚本。当我执行它时,我收到此错误消息: Traceback (most recent call la
首先,执行此操作(在运行 4.4.2 的 Nexus 5 上测试): 将 PRIORITY_LOW 通知传递给 Service.startForeground()。 观察通知不显示在状态栏中。 使用相
我尝试使用 AppEngine 的 python 模块 api 来获取使用基本缩放的模块的实例数。在我模块的 yaml 文件中,我明确设置了 max_instances 参数。我希望 get_num_
当我如下运行我的 spark python 代码时: import pyspark conf = (pyspark.SparkConf() .setMaster("local")
在我的系统上,一段适用于 Python 2 的代码不适用于 Python 3。 f = open("plotwidget.svg") svgData = f.read() xml_stream = Q
我是 PHP 和 SQL 的新手,但我正在创建一个登录系统。我遇到的问题是: You have an error in your SQL syntax; check the manual that c
我有一个使用 ebaysdk 库的 python 代码,当我运行代码并输入关键字进行搜索时,我得到了这个错误。 Traceback (most recent call last): File "eba
当我将表单数据发送到我的 Flask 应用程序时,出现以下错误。它说它将使用 UTF-8 编码,但语言环境已经是 UTF-8。这个错误是什么意思? /home/.virtualenvs/project
在python2.7中,跟随pympler example : from anotherfile import somefunction, somecustomclass from os import
我是一名优秀的程序员,十分优秀!