【问题标题】:I am having trouble with this kind of exercises. I am getting again.. this error Segmentation fault (core dumped). Any suggestions?我在做这种练习时遇到了麻烦。我又来了..这个错误分段错误(核心转储)。有什么建议?
【发布时间】:2020-09-09 19:36:05
【问题描述】:

我创建了一个从用户 N 元素获取的 (int *) 表,然后在我创建的交换和排序函数的帮助下打印出排序表。代码如下:

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

void swap(int **p_a, int **p_b);
void sort(int **table, int N);

int main(void){
    // Here your code !

    int *table;
    int elements, i;

    printf("Input the number of elements to store in the array : ");
    scanf("%d", &elements);

    table = (int *)malloc(elements * sizeof(int));
    if (table == NULL)
    {
        printf("Unable to allocate memory...");
        return -1;
    }

    printf("Input %d number of elements in the array : \n", elements);
    for (i=0; i<elements; i++)
    {
        printf("element - %d: ", i+1);
        scanf("%d", (table + i));
    }

    printf("\nThe elements in the array before sorting: \n");
    for (i=0; i<elements; i++)
        printf("element - %d : %d\n", i+1, *(table + i));


    sort(&table, elements);


    printf("\nThe elements in the array after sorting: \n");
    for (i=0; i<elements; i++)
        printf("element - %d : %d\n", i+1, table[i]);


    free(table);
} 

void swap(int **p_a, int **p_b)
{
    int temp;

    temp = **p_a;

    **p_a = **p_b;
    **p_b = temp;
}

void sort(int **table, int N)
{
    int i,j;
    int current_position;
    for (i=0; i<N; i++)
    {
        current_position = i; // current_position is the current element of the table
        for (j=i; j<N; j++)
        {
            /* 
                compares all the elements after the current position
                if the condition is true then the current position now is the next position, and compares it again.
                When the outer loop will loop again it means that the smallest element was found and then compares the other ones
            */
            if (*table[j] < *table[current_position]); 
                current_position = j;
        }

        swap(&table[current_position], &table[j]);
    }
}

控制台:

Input the number of elements to store in the array : 5
Input 5 number of elements in the array : 
element - 1: 5
element - 2: 99
element - 3: 22
element - 4: 1
element - 5: 0

The elements in the array before sorting: 
element - 1 : 5
element - 2 : 99
element - 3 : 22
element - 4 : 1
element - 5 : 0

错误:

Segmentation fault (core dumped)

有什么建议吗?我的函数结构是否正确,函数参数是否正确?对于排序中的代码,我 100% 确定这是正确的。

【问题讨论】:

  • 您已经发布了几个这样的问题。是时候开始学习如何使用调试器来诊断这些错误了。盯着代码看不是很有效,尤其是对于非专家而言,并且每次都询问 StackOverflow 并不是一个很好的长期解决方案。
  • 其他需要了解的工具是 malloc 调试器(例如 valgrind)或其他内存清理器(例如 gcc -fsanitize=address)。
  • 另外,启用编译器警告,和/或尝试提供比当前版本更好的警告的编译器。 gcc 对if (*table[j] &lt; *table[current_position]); 发出警告,其中尾随分号导致它不执行您想要的操作,并且以下行无条件执行。 (教训:程序中“100% 确定正确”的部分通常是错误所在。:-)
  • @NateEldredge 感谢您的建议
  • 回滚以免隐藏证据。这不是代码需要修复的地方:它在您自己的机器上。

标签: c function sorting malloc


【解决方案1】:

sortswap 的声明中,您的间接级别太多了。你的声明应该是:

void swap(int *p_a, int *p_b);
void sort(int *table, int N);

您的swap 可以是:

void swap(int *p_a, int *p_b)
{
    int temp;

    temp = *p_a;

    *p_a = *p_b;
    *p_b = temp;
}

您的sort 看起来是冒泡排序和插入排序的混合体。选择一个或另一个。稍加修改,一个简单的冒泡排序将是:

void sort(int *table, int N)
{
    int i,j;

    for (i=0; i<N; i++)
    {
        for (j=i; j<N; j++)
        {
            if (table[j] < table[i])
                swap(&table[i], &table[j]);
        }
    }
}

在您的if 语句末尾修复错位的';' 并将您的呼叫更改为sort(table, elements); 后,您将收到:

使用/输出示例

$ ./bin/sortandswap
Input the number of elements to store in the array : 5
Input 5 number of elements in the array :
element - 1: 5
element - 2: 99
element - 3: 22
element - 4: 1
element - 5: 0

The elements in the array before sorting:
element - 1 : 5
element - 2 : 99
element - 3 : 22
element - 4 : 1
element - 5 : 0

The elements in the array after sorting:
element - 1 : 0
element - 2 : 1
element - 3 : 5
element - 4 : 22
element - 5 : 99

在C语言中,malloc的返回不需要强制转换,没有必要。请参阅:Do I cast the result of malloc?。如果您使用取消引用的指针来设置您的 type-size,您就消除了出错的机会。使用取消引用的指针来设置 type-size 的正确用法是:

table = malloc(elements * sizeof *table);

编辑 - 回复评论

tablemain() 中的整数指针,那里没有变化。对分配所做的唯一更改是使用取消引用的指针来设置 type-size 而不是 sizeof(int)。在微不足道的情况下,就像这里一样,使用错误的 type-size 的可能性很小(尽管我经常看到它)。当分配指向可能有许多成员的结构之类的对象的指针时,好处就来了。这里:

int *table;
...
table = malloc(elements * sizeof *table);

相当于:

table = malloc(elements * sizeof(int));

(其中table 是指向int 的指针,因此*table 只是类型int

为了证明table 仍然是一个指向 int 的指针,完整的例子是:

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

void swap(int *p_a, int *p_b);
void sort(int *table, int N);

int main(void){
    // Here your code !

    int *table;
    int elements, i;

    printf("Input the number of elements to store in the array : ");
    scanf("%d", &elements);

    table = malloc(elements * sizeof *table);
    if (table == NULL)
    {
        printf("Unable to allocate memory...");
        return 1;
    }

    printf("Input %d number of elements in the array : \n", elements);
    for (i=0; i<elements; i++)
    {
        printf("element - %d: ", i+1);
        scanf("%d", (table + i));
    }

    printf("\nThe elements in the array before sorting: \n");
    for (i=0; i<elements; i++)
        printf("element - %d : %d\n", i+1, *(table + i));


    sort(table, elements);


    printf("\nThe elements in the array after sorting: \n");
    for (i=0; i<elements; i++)
        printf("element - %d : %d\n", i+1, table[i]);


    free(table);
} 

void swap(int *p_a, int *p_b)
{
    int temp;

    temp = *p_a;

    *p_a = *p_b;
    *p_b = temp;
}

void sort(int *table, int N)
{
    int i,j;

    for (i=0; i<N; i++)
    {
        for (j=i; j<N; j++)
        {
            if (table[j] < table[i])
                swap(&table[i], &table[j]);
        }
    }
}

(注意:main() 失败后,不要将 值返回给 shell。C 定义了两个要返回给 shell 的退出值,@ 987654347@(值为0)和EXIT_FAILURE(值为1))

【讨论】:

  • 我理解您在上面评论的所有内容。唯一的事情是我希望表是一个整数指针,所以我可以在 main 中进行 malloc,如果你知道我想说什么?因此,如果我要这样做,我必须对表进行**。我也是一名 ECE 学生,所以要分配内存,我们必须使用我上面写的命令,并使用类型转换以获得可读代码。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-28
  • 2017-06-26
  • 1970-01-01
  • 2019-05-05
  • 2021-06-23
  • 1970-01-01
相关资源
最近更新 更多