C语言 为什么当for循环完成向列表添加元素时,我会得到一个segfault?

nnt7mjpx  于 2022-12-17  发布在  其他
关注(0)|答案(1)|浏览(126)

我的代码是一个算法,它首先解决一个与最长作业相关的问题。它接收进程的数量(num_programas),并为每个进程获得一个时间(instante)和一个权重(carga)。当我插入到列表中时,它插入所有进程,但在最后一个进程中,它得到了分段错误。
它是正常排序的(每次循环执行时我都打印了头文件),它只是在for循环的最后一次执行中出现了分段错误(例如:程序数= 7,当i = 6时停止工作)

/*

Vou fazer com lista duplamente encadeada só pra facilitar na funcao proximo. Não vou otimizar porque preciso me livrar
logo pra fazer o projeto e estudar

puta merda que codigo horrivel, espero que o aleardo nao leia. Otimizar depois.

8
74 11 
7 20
53 17
78 13
52 11
63 19
89 17
15 20
*/
#include <stdio.h>
#include <stdlib.h>
struct processo
{
    int temp;
    int carga;
    struct processo *next;
    struct processo *prev;
};

struct processo *cadastrarProcesso(struct processo *header, int instante, int carga);
struct processo *executarAtividade(struct processo *header, int *tempo_executando);
struct processo *inserirProcessos(struct processo *programa, struct processo *header);
void imprimirLista(struct processo *header);
struct processo *proximo(struct processo *header, int *tempo_executando);

int main()
{
    struct processo *header, *aux;
    header = NULL;
    int num_programas, instante, carga, i, tempo_executando = 0;
    scanf("%d", &num_programas);
    for (i = 0; i < num_programas; i++)
    {
        scanf("%d %d", &instante, &carga);
        header = cadastrarProcesso(header, instante, carga);
    }
    /*
        Cadastrou e ordenou em ordem de tempo, aí tem que criar uma funcao para ir printando
    */

    imprimirLista(header);

    for (i = 0; i < num_programas; i++)
    {
        header = executarAtividade(header, &tempo_executando);
    }

    return 0;
}
struct processo *cadastrarProcesso(struct processo *header, int instante, int carga)
{
    struct processo *aux;
    aux = malloc(sizeof(struct processo));
    aux->next = NULL;
    aux->prev = NULL;
    aux->carga = carga;
    aux->temp = instante;
    header = inserirProcessos(aux, header);
    return header;
}
struct processo *inserirProcessos(struct processo *programa, struct processo *header)
{
    struct processo *aux;
    if (header == NULL)
    {
        header = programa;
        return header;
    }
    aux = header;
    while (aux->next != NULL && programa->temp > aux->temp)
    {
        aux = aux->next;
    }

    if (aux == header)
    {
        // tem que fazer essa verificacao pq ele sai do while tanto se o while->next for nulo e tambem se for maior
        if (programa->temp < aux->temp)
        {
            // insere depois do header, se tornando o novo header
            aux->prev = programa;
            programa->next = aux;
            return programa;
            // é o novo header, retorna ele
        }

        else // insere depois)
        {
            programa->next = aux->next;
            aux->next = programa;
            programa->prev = aux;

            return header;
        }
    }
    else
    {
        // vamos ver se ele saiu porque while->next é nulo ou porque é maior
        if (programa->temp < aux->temp)
        {
            (aux->prev)->next = programa;
            programa->prev = aux->prev;
            programa->next = aux;
            aux->prev = programa;
            return header;
        }
        else // maior igual
        {
            programa->next = aux->next;
            programa->prev = aux;
            aux->next = programa;
            return header;
        }
    }
}

void imprimirLista(struct processo *header) // funcao auxiliar
{
    struct processo *aux;
    aux = header;
    while (aux != NULL)
    {
        printf("%d ", aux->temp);
        aux = aux->next;
    }
}

struct processo *executarAtividade(struct processo *header, int *tempo_executando)
{

    // lembrando que já está dentro de um for
    struct processo *aux;
    if (*tempo_executando == 0)
    {
        aux = header;
        *tempo_executando = aux->temp + aux->carga;
        header = aux->next;
        printf("%d ", aux->carga); // imprime a carga da saida que foi executada
        (aux->next)->prev = NULL;
        aux->next = NULL;
        free(aux);
        return header;
    }
    else
    {
        // TODO: reduzir esse codigo zendo tudo dentro do mesmo IF, só olhando a condicao do proximo

        aux = proximo(header, tempo_executando); // recebe o que vai ser executado
        *tempo_executando = *tempo_executando + aux->carga;
        if (aux == header) // se o aux
        {
            header = aux->next;
            printf("%d ", aux->carga);
            (aux->next)->prev = NULL;
            aux->next = NULL;
            free(aux);
            return header;
        }
        else
        {

            if (aux->next != NULL)
            {
                (aux->next)->prev = aux->prev;
                (aux->prev)->next = aux->next;
            }
            else
            {
                (aux->prev)->next = aux->next;
            }
            printf("%d ", aux->carga);
            free(aux);
            return header;
        }
    }
}
struct processo *proximo(struct processo *header, int *tempo_executando)
{
    struct processo *aux, *escolhido;
    int maior_carga;
    aux = header;
    maior_carga = aux->carga;
    escolhido = aux;
    if (aux->temp >= *tempo_executando)
    {
        //*tempo_executando = *tempo_executando + (aux->temp - *tempo_executando);
        return aux;
    }
    else
    {
        while (aux->next != NULL && aux->temp < *tempo_executando)
        {
            aux = aux->next;

            if (aux->carga > maior_carga)
            {
                maior_carga = aux->carga;
                escolhido = aux;
            }
            else if (aux->carga == maior_carga)
            {
                // o critério de desempate é o menor tempo
                if (aux->carga < escolhido->carga)
                {
                    escolhido = aux;
                }
            }
        }
        return escolhido;
    }
}
cyvaqqii

cyvaqqii1#

在此代码中:

if (aux == header) // se o aux
        {
            header = aux->next;
            printf("%d ", aux->carga);
            (aux->next)->prev = NULL;  // crash here with aux->next == NULL
            aux->next = NULL;
            free(aux);
            return header;
        }

删除最后一个元素(aux == header)时,aux->nextNULL,尝试取消引用它会导致崩溃。在执行此操作之前,必须检查aux->next != NULL
如果你立即调用free(aux)aux->next = NULL是无用的。

相关问题