为什么我在大输入时遇到 scanf 的分段错误
why I am getting segmentation fault with scanf at large inputs
我已经编写了 C 代码来对输入数组进行归并排序
我尝试了 2 3 5 10 100 1000 10,000 和 1,000,000 的代码
除了 10,000 和 1,000,000,它在所有情况下都按预期工作
调试后发现错误在scanf() code
内
Program received signal SIGSEGV, Segmentation fault.
0x00000000004006a7 in main () at merge.c:10
10 scanf("%i",&array[i]);
但就我而言代码是完全正确的
int len;
scanf("%i",&len);
int array[len];
for(int i=0; i<len;i++)
{
scanf("%i",&array[i]);
}
如果您需要完整的代码来进行澄清,请点击此处
#include <stdio.h>
void mergesort(int* list , int len);
int main()
{
int len;
scanf("%i",&len);
int array[len];
for(int i=0; i<len;i++)
{
scanf("%i",&array[i]);
}
mergesort(array,len);
for(int i=0; i<len;i++) printf("%i\n",array[i]);
printf("\b");
}
void mergesort (int* list, int len)
{
if(len == 1) return;
int i = len/2, j = len-i;
int list1[i], list2[j];
for(int k=0;k<i;k++)
{
list1[k]= list[k];
list2[k]= list[i+k];
}
if(len%2!=0) list2[j-1] = list[len-1];
mergesort(list1 , i);
mergesort(list2 , j);
int k=0,l=0;
// k represent counter over elements in list1
// l represent counter over elements in list2
// k+l represent counte over total elements in list
while(k+l!=len)
{
if(k==i)
{
for(;l<j;l++) list[k+l] = list2[l];
return;
}
else if (l==j)
{
for(;k<i;k++) list[k+l] = list1[k];
}
else if(list1[k]<list2[l])
{
list[k+l]=list1[k];
k++;
}
else if(list1[k]>list2[l])
{
list[k+l] = list2[l];
l++;
}
else
{
//handles dublication
list[k+l] = list1[k];
k++;
list[k+l] = list[l];
l++;
}
}
}
EDIT:
如果您认为问题与平台有关,我使用 ubuntu 14.04
和 gnu c 编译器 4.8.2,我用标志 -std=c99 -Wall
编译代码
并且没有错误和警告
合并排序会占用大量内存,并且您要在 c 程序员称为堆栈 (int list1[i], list2[j];
) 的地方分配额外的内存。实际上堆栈中的空间很小。反复做大的值超出了限制
您必须改用 heap 分配 - 动态分配。堆有大量可用于分配的内存,可用于大型数组等用途。你这样做:
//C example with malloc, ALWAYS use sizeof
int *array = (int*) malloc( length * sizeof(int));
//C++ way
int *array = new int[length];
但是程序结束后内存仍然分配,除非你释放它。在这种情况下这可能是个问题。 确保在不再需要时取消分配它。
//C way
free(array);
//C++ way for arrays
delete[] array;
//C++ way for single heap values
delete value;
这是正确的方式,你应该习惯它,因为你以后非常需要动态分配。
我已经编写了 C 代码来对输入数组进行归并排序 我尝试了 2 3 5 10 100 1000 10,000 和 1,000,000 的代码 除了 10,000 和 1,000,000,它在所有情况下都按预期工作 调试后发现错误在scanf() code
内Program received signal SIGSEGV, Segmentation fault.
0x00000000004006a7 in main () at merge.c:10
10 scanf("%i",&array[i]);
但就我而言代码是完全正确的
int len;
scanf("%i",&len);
int array[len];
for(int i=0; i<len;i++)
{
scanf("%i",&array[i]);
}
如果您需要完整的代码来进行澄清,请点击此处
#include <stdio.h>
void mergesort(int* list , int len);
int main()
{
int len;
scanf("%i",&len);
int array[len];
for(int i=0; i<len;i++)
{
scanf("%i",&array[i]);
}
mergesort(array,len);
for(int i=0; i<len;i++) printf("%i\n",array[i]);
printf("\b");
}
void mergesort (int* list, int len)
{
if(len == 1) return;
int i = len/2, j = len-i;
int list1[i], list2[j];
for(int k=0;k<i;k++)
{
list1[k]= list[k];
list2[k]= list[i+k];
}
if(len%2!=0) list2[j-1] = list[len-1];
mergesort(list1 , i);
mergesort(list2 , j);
int k=0,l=0;
// k represent counter over elements in list1
// l represent counter over elements in list2
// k+l represent counte over total elements in list
while(k+l!=len)
{
if(k==i)
{
for(;l<j;l++) list[k+l] = list2[l];
return;
}
else if (l==j)
{
for(;k<i;k++) list[k+l] = list1[k];
}
else if(list1[k]<list2[l])
{
list[k+l]=list1[k];
k++;
}
else if(list1[k]>list2[l])
{
list[k+l] = list2[l];
l++;
}
else
{
//handles dublication
list[k+l] = list1[k];
k++;
list[k+l] = list[l];
l++;
}
}
}
EDIT:
如果您认为问题与平台有关,我使用 ubuntu 14.04
和 gnu c 编译器 4.8.2,我用标志 -std=c99 -Wall
编译代码
并且没有错误和警告
合并排序会占用大量内存,并且您要在 c 程序员称为堆栈 (int list1[i], list2[j];
) 的地方分配额外的内存。实际上堆栈中的空间很小。反复做大的值超出了限制
您必须改用 heap 分配 - 动态分配。堆有大量可用于分配的内存,可用于大型数组等用途。你这样做:
//C example with malloc, ALWAYS use sizeof
int *array = (int*) malloc( length * sizeof(int));
//C++ way
int *array = new int[length];
但是程序结束后内存仍然分配,除非你释放它。在这种情况下这可能是个问题。 确保在不再需要时取消分配它。
//C way
free(array);
//C++ way for arrays
delete[] array;
//C++ way for single heap values
delete value;
这是正确的方式,你应该习惯它,因为你以后非常需要动态分配。