【问题标题】:How to avoid SIGSEGV Error in Insertion Sort如何避免插入排序中的 SIGSEGV 错误
【发布时间】:2018-07-29 03:00:21
【问题描述】:

我正在尝试在 C 中实现插入排序算法。 但我得到的只是在线 IDE 中的 SIGSEGV 错误,并且输出未显示在 Code::Blocks 中。如何避免此类错误。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    /* Here i and j are for loop counters, temp for swapping
       count  for total number of elements,array for elements*/

    int i, j, temp, count;
    printf("How many numbers are you going to enter");
    scanf("%d", &count);
    int n[20];
    printf("Enter %d elements", count);

    // storing elements in the array
    for(i = 0; i < count; i++) {
        scanf("%d", n[i]);
    }

    // Implementation of insertion sort algorithm
    for(i = 0; i < count; i++) {
        temp = n[i];
        j = i - 1;

        while(temp < n[j]) {
            n[j+1] = n[j];
            j = j - 1;
        }
        n[j+1] = temp;
    }

    printf("Order of sorted elements");
    for(i = 0; i < count; i++) {
        printf("%d", n[i]);
    }

    return 0;
}

【问题讨论】:

  • 你读过编译器警告吗?这 scanf("%d",n[i]); --> scanf("%d",&amp;n[i]); 。另外如果 count 大于 20 怎么办?它会导致未定义的行为。
  • 什么时候是n[-1],即i=0j = i-1
  • 给自己一个真正的 IDE,可以是 Windows 的 Visual Studio 社区,也可以是 MacOS / Linux 下免费提供的任何东西。能够在受控的调试环境中运行您的代码使得查找此类错误变得更加容易。如果您的开发环境没有停在发生崩溃的那一行,并允许您“事后”检查变量,那么是时候用更好的东西替换它了。

标签: c runtime-error insertion-sort


【解决方案1】:

您的代码存在一些问题。首先,什么是 SIGSEGV 错误?嗯,它是旧的Segmentation fault 错误的别称,基本上就是你访问无效内存时遇到的错误(即不允许访问的内存)。

  1. tl;dr:scanf("%d",n[i]); 更改为 scanf("%d",&amp;n[i]);。您正在尝试使用scanf("%d",n[i]); 读取初始值,这会引发分段错误错误,因为scanf 需要 addresses 将读取的值放入其中,但您真正要做的是传递n[i]value 好像它是一个地址(它不是,因为你还没有为它设置任何值,它几乎只是内存垃圾)。更多关于 here.

  2. tl;dr:int n[20]; 更改为 int n[count]。你的数组声明 int n[20]; 最多存储 20 个整数,如果有人想要插入 21 个或更多值会发生什么?您的程序保留了一定的堆栈(内存)空间,如果超过该空间,那么您将偶然发现另一个程序的空间,并且警察(内核)会逮捕您(分段错误)。 提示:尝试插入 21 和 100 值,看看会发生什么。

  3. tl;dr:for(i = 0; i &lt; count; i++) { 更改为 for(i = 1; i &lt;= count; i++) {。这是您的索引的逻辑问题,您从i = 0 开始直到i = count - 1,这在大多数数组迭代情况下都是正确的,但由于j 假定i 之前的索引值,您需要@ 987654342@ 从1 开始(所以j0,否则在第一次迭代中j = -1(不是有效索引)。

我的最终代码如下。希望对您有所帮助,祝您编码愉快!

#include <stdio.h>
#include <stdlib.h>

int main() {
    /*Here i and j are for loop counters,temp for swapping
    count  for total number of elements,array for elements*/
    int i, j, temp, count;
    printf("How many numbers are you going to enter?\n");
    scanf("%d",&count);
    int n[count];
    printf("Enter %d elements\n",count);
    //storing elements in the array
    for(i = 0; i < count; i++) {
        scanf("%d", &n[i]);
    }
    //Implementation of insertion sort algorithm
    for(i = 1; i <= count; i++) {
        temp = n[i];
        j = i-1;
        while(temp < n[j]) {
            n[j+1] = n[j];
            j--;
        }
        n[j+1] = temp;
     }
     printf("Order of sorted elements\n");
     for(i = 0; i < count; i++) {
        printf("%d\n",n[i]);
     }
    return 0;
}

编辑:如果您在使用在线 IDE 时遇到问题,请考虑在本地运行您的程序,这样可以节省大量时间,此外:您永远不知道在线 IDE 使用的是什么内核版本或魔法运行您的代码(相信我,当您使用 C 进行编码时——相当低级的语言,这些事情有时会有所作为)。我喜欢使用 Vim 作为文本编辑器和 gcc 进行编译以及使用 gdb 进行调试的所有 root 样式。

【讨论】:

  • 谢谢,我忘了在scanf中添加“&”。为什么我不会因为那个错误而收到错误消息?
  • 如果您使用的是在线 IDE,编译器的选项可能对您不可用。但是你可以download gcc 并指定选项-Wall(警告所有),你应该看到一个警告抱怨。 warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘int’ [-Wformat=] 另外,请务必标记答案并检查它是否对您有帮助:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多