【问题标题】:Why is my program giving me an Abort Trap: 6 error?为什么我的程序给我一个 Abort Trap: 6 错误?
【发布时间】:2016-02-07 08:45:46
【问题描述】:

这段代码应该对字符串数组进行排序,但是在选择排序中主循环的第二次迭代时,它给了我一个 Abortion Trap: 6 错误。我在 Mac 的终端上运行它。这是代码

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

int letSize = 20;
int vecSize;
char **array1;

void selectionSort (int low, int high)
{
    char *temp = malloc ((letSize + 1) * sizeof (char));
    int i = 0, j = 0;

    for (i = low; i < high - 1; i++) {
        int indexOfMin = i;
        for (j = i + 1; j < high; j++)
            if (strcmp (array1[j], array1[indexOfMin]) < 0)
                indexOfMin = j;
        //after second main loop, error occurs
        strcpy (temp, array1[i]);
        strcpy (array1[i], array1[indexOfMin]);
        strcpy (array1[indexOfMin], temp);
    }
}

int main ()
{
    int i, j;

    printf ("Enter size of items to be sorted: ");
    scanf ("%d", &vecSize);
    array1 = malloc (vecSize * sizeof (char *));
    for (i = 0; i < vecSize; i++)
        array1[i] = malloc ((letSize + 1) * sizeof (char));

    srand (time (NULL));
    for (i = 0; i < vecSize; i++) {
        for (j = 0; j <= letSize; j++) {
            if (j != letSize) {
                char randLet = 'A' + (random () % 26);
                array1[i][j] = randLet;
            } else
                array1[i][j] = '\0';
        }
    }
    selectionSort (0, vecSize);
}

这是给我带来麻烦的代码。它编译没有任何问题,它也接受用户的输入,但之后它给了我 abort trap 的错误: 6. 可能是什么原因造成的? 提前致谢。

【问题讨论】:

  • 只是我的(正确)意见:selectionSort 不应该被告知向量有多大。
  • 好点。我使用的是模板代码,但该代码不依赖于全局变量。感谢您的提醒
  • 查看您的 sort 例程,看起来有多个问题,首先是缺少括号 '{...} 包装了 if (strcmp... 子句。即使有这种变化,我也不肯定这是一个正确的选择排序。您需要确认。
  • 与你的问题没有直接关系,但是你的数据是一个指针数组;为什么要交换字符串而不是只交换指针? IE。使用普通赋值而不是strcpys,并在排序函数中去掉malloc
  • @DavidC.Rankin 来吧,大括号只是一个代码风格点,并不是普遍接受的。想详细说明您看到的“多个问题”吗?否则你的评论有点不具建设性。

标签: c macos


【解决方案1】:

问题是当j == indexOfMin(或j == i)尝试使用strcpy(您可以使用memmove,而不是strcpy)复制重叠的内存区域时,您尝试进行复制。来自man strcpy

strcpy()函数复制src指向的字符串,包括 终止空字节 ('\0'),指向 dest 指向的缓冲区。 The strings may not overlap, ....

您只需要检查并仅在j != indexOfMin 时进行复制,以防止尝试将字符串复制到自身之上。例如:

void selectionSort (int low, int high)
{
    char *temp = malloc ((letSize + 1) * sizeof (char));
    int i = 0, j = 0;

    for (i = low; i < high - 1; i++) {
        int indexOfMin = i;
        for (j = i + 1; j < high; j++)
            if (strcmp (array1[j], array1[indexOfMin]) < 0)
                if (j != indexOfMin) {
                    indexOfMin = j;
                    strcpy (temp, array1[i]);
                    strcpy (array1[i], array1[indexOfMin]);
                    strcpy (array1[indexOfMin], temp);
                }
    }
    free (temp);
}

还记得free (temp),否则你肯定会出现内存泄漏。

【讨论】:

  • 虽然您对strcmp 的评论在形式上是正确的,但实际上这种特定情况不会在所有现有实现中造成任何问题。所以 topickstarter 崩溃的原因一定是别的原因。
  • 这将取决于实现。我没有看过apple 源代码,但我怀疑它与Linux 实现不同。它并没有导致我的 Linux 机器崩溃,但显然他的实现正在捕获内存错误。通过valgrind 运行它并查看。
  • 调试版本中的参数检查?可能是,点承认。虽然我希望这样的检查带有assert-like 人类可读的输出。
  • 指针交换是要走的路。消除了这个问题,并保存了对 mallocstrcpy 等的一些调用。对我来说,这再次提醒我重命名循环变量如何使更难直观地看到问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-05
  • 2021-07-22
  • 2020-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多