为什么我会收到 SIGABRT?

Why am I getting SIGABRT?

// Sort the given numbers in non decreasing order
// such that even and odd numbers are alternatively
// fit inside the array.

#include <stdio.h>

void swap(int* a, int* b)
{
    int t;

    t  = *a;
    *a = *b;
    *b =  t;
}

void sort(int* arr, int size)
{
    int i, j;

    for (i = 0; i < size - 1; ++i)
        for (j = 0; j < size - i - 1; ++j)
            if (arr[j] > arr[j + 1])
                swap(arr + j, arr + j + 1);
}

void print_arr(int* arr, int size)
{
    for (int i = 0; i < size; ++i)
        printf("%d ", arr[i]);
    printf("\n");
}

void rearrange(int* arr, int size)
{
    // have two arrays to store odds and evens
    int odds[size], evens[size];
    int i, j, k;

    // sort the array
    sort(arr, size);

    // populate the two arrays
    for (i = 0, j = 0, k = 0; i < size; ++i)
    {
        if (arr[i] % 2) odds[j++] = arr[i];
        else evens[k++] = arr[i];
    }

    print_arr(odds, j);
    print_arr(evens, k);

    // check the first elements of `odds` and `evens`
    // in order to decide which ones occupy
    // the odd and even indices
    int* first;
    int* second;

    if (odds[0] < evens[0]) 
    {
        first = odds;
        second = evens;
    } else {
        first = evens;
        second = odds;
        swap(&j, &k);
    }

    // populate the odd and even indices of `res`
    i = 0;
    while (j >= 0)
    {
        arr[i] = first[--j];
        i += 2;
    }

    i = 1;
    while (k >= 0)
    {
        arr[i] = second[--k];
        i += 2;
    }
}

int main()
{
    int nums[] = { 80, 54, 0, 9, 6, 5, 4, 67, 1}; // SIGABRT
    // int nums[] = { 80, 54, 9, 5, 4, 67, 1};
    rearrange(nums, 9);
    print_arr(nums, 9);
    return 0;
}

这运行得很好,但是在 之后 它实际上打印出了结果。这在我尝试过的任何其他情况下都没有发生。从调试会话中,我可以看到它在 print_arr 完成之前工作正常,但在 returns 到 main 之后抛出一个 SIGABRT,那是在它实际打印出结果之后控制台。我还没弄明白为什么。

调试器输出:

* thread #1, queue = 'com.apple.main-thread', stop reason = step over
    frame #0: 0x0000000100000f01 odd_even`main at odd_even.c:89:5
   86       int nums[] = { 80, 54, 0, 9, 6, 5, 4, 67, 1}; // SIGABRT
   87       // int nums[] = { 80, 54, 9, 5, 4, 67, 1};
   88       rearrange(nums, 9);
-> 89       print_arr(nums, 9);
   90       return 0;
   91   }
   92
Target 0: (odd_even) stopped.
(lldb)
80 67 54 9 6 5 4 1 0
Process 2580 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
    frame #0: 0x00007fff6be8249a libsystem_kernel.dylib`__pthread_kill + 10
libsystem_kernel.dylib`__pthread_kill:
->  0x7fff6be8249a <+10>: jae    0x7fff6be824a4            ; <+20>
    0x7fff6be8249c <+12>: movq   %rax, %rdi
    0x7fff6be8249f <+15>: jmp    0x7fff6be7c3b7            ; cerror_nocancel
    0x7fff6be824a4 <+20>: retq
Target 0: (odd_even) stopped.

你可以看到我确实得到了输出,但在那之后得到了信号。

当您 填充 res 的奇数和偶数索引时,您的循环 运行 当 jk 是零。这会导致赋值 arr[i] = first[--j];arr[i] = second[--k]; 在访问元素 first[-1]second[-1] 时访问分配的 space 的边界之外。但是,这导致的大问题是您正在向 arr 写入两个额外的元素,这也是未定义的行为。在这种情况下,这将破坏调用方 (main) 中的堆栈,从而导致在 main returns.

时崩溃