我为什么要获得SIGABRT?

问题描述 投票:0回答:1
// 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;
}

这运行得很好,但是抛出SIGABRT after,它实际上会打印出结果。在我尝试过的任何其他情况下都没有发生这种情况。从调试会话中,我可以看到在print_arr完成之前它可以正常工作,但是在返回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.

您可以看到我确实得到了输出,但是之后得到了信号。

c sigabrt
1个回答
0
投票

当<res的奇数和偶数索引时>,当jk为零时,循环运行。当访问元素arr[i] = first[--j];arr[i] = second[--k];时,这会导致分配first[-1]second[-1]访问分配空间的边界之外。但是,这引起的最大问题是您正在向arr写入两个附加元素,这也是未定义的行为。在这种情况下,这将破坏调用者(main)中的堆栈,当main返回时会导致崩溃。

© www.soinside.com 2019 - 2024. All rights reserved.