首页 文章

main()上没有参数的分段错误

提问于
浏览
0

我有这个简单的bubblesort程序,当在macOs上编译时可以正常工作,但是当在linux上编译时(使用gcc),在运行时会出现分段错误 . 我很想知道为什么 .

#include <stdio.h>
#include "alg_utils.h"

void bubble_sort(int *, int);

int main() {
    int array[10] = {5, 10, 77, 1, -2, -61, 18, 14, 57, 7};
    bubble_sort(array, 10);
    print_array(array, 10);
    return 0;
}

void bubble_sort(int *array, int len) {
    int i, j;

    for (i=0; i < len; i++) {
        for (j=0; j < len; j++) {
            if (array[j] < array[j-1])
               swap(&array[j], &array[j-1]);
        }
    }
}

On mac:

~/Projects/Algorithms: gcc Bubblesort.c
~/Projects/Algorithms: ./a.out
  -2   0   1   5   7  10  14  18  57  77%

On linux:

root#f95445bcd4e7:~/algos$ gcc Bubblesort.c
root#f95445bcd4e7:~/algos$ ./a.out
Segmentation fault

alg_utils.h只有swap()和print_array()函数的定义 . 没什么了不起的 .

void print_array(int *, int);
void swap(int *, int *);

void swap(int *a, int *b) {
    int temp = *b;
    *b = *a;
    *a = temp;
}

void print_array(int *array, int len) {
    int i;
    for (i=0; i < len; i++) {
        printf("%4d", array[i]);
    }
}

当我用main(int argc,char * argv [])更改main()时,它也适用于linux .

*Linux (with main(int argc, char argv[])

root#f95445bcd4e7:~/algos$ gcc Bubblesort.c
 root#f95445bcd4e7:~/algos$ ./a.out
 -2   1   1   5   7  10  14  18  57  77

所以我想:linux不喜欢main而没有params ...但是这样一个简单的hello world就可以了 .

#include <stdio.h>
int main() {
    printf("hello world\n");
    return 0;
}

所以,我很困惑 . 它是什么?也许alg_utils?也许不同的c实现?我尝试使用-std = c99(和其他组合)进行编译无济于事 .

有人有任何线索吗?先感谢您

2 回答

  • 0
    for (i=0; i < len; i++) {
            for (j=0; j < len; j++) {
                if (array[j] < array[j-1])
                   swap(&array[j], &array[j-1]);
            }
    }
    

    在你的for循环中,你试图访问 array[j-1] 所以当 j=0 的值实际上你正在尝试访问数组外的内存位置时,这个内存位置可能没有分配给你,所以这会导致 segmentation fault .

    现在C编译器根据操作系统,编译器版本等许多因素表现不同 . 据我所知,Mac OS必须在阵列前后保留一些填充,以便即使您访问这些内存位置,您的程序也会赢得'崩溃(再次,我在这里太简短了,还有更多的东西!) . 另一方面,Linux不能为您提供填充,并且正在分配您需要的确切内存量!因此,当您访问未分配的内存时,它会给您分段错误并导致程序崩溃!

    检查此链接有关我正在谈论的填充: - https://en.wikipedia.org/wiki/Buffer_overflow_protection

    EDIT :- 我忘记提到这一点,当你用main参数编写时,你的程序是有效的,因为为 argv[] 保留了一些空间,幸运的是当你访问 array[j-1] 时,你必须访问可用的内存位置,即 argv[] . (这个解释非常简短,有很多技术方面的内容!)

    希望这可以帮助 :)

  • 1

    不要这样做:

    for (i=0; i < len; i++) {
        for (j=0; j < len; j++) {
            if (array[j] < array[j-1])
               swap(&array[j], &array[j-1]);
        }
    }
    

    改用它:

    for (i=0; i < len; i++) {
        for (j=i+1; j < len; j++) {
            if (array[i] < array[j])
               swap(&array[i], &array[j]);
        }
    }
    

    这种方法不会访问超出数组限制的元素,工作速度提高两倍,因为它不会分析已排序的数组部分 .

相关问题