为什么我在c中使用堆内存时遇到运行时错误?

时间:2014-11-23 15:23:45

标签: c segmentation-fault malloc

我一直在解决一个需要约瑟夫问题和大量素数的问题....

这是我的代码......

/*
    josephus problem.uri judge:1030
    author :: R_H_T

*/


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

int count;
//int *c = &count;

typedef struct node{                            // make a a linked list structure node with a number,next node and previous node
    int number;
    struct node *next;
    struct node *previous;
} node;

node* create (int n){                           //create nodes      
    node *nd = malloc(sizeof(node));
    nd->number = n;
    nd->next = NULL;
    nd->previous = NULL;
    return nd;
}

void kill(node *n){                             // set node.numbers = 0
        n->number = 0;
        //free(n);

}

node* next_node(node *n,int step){              // decide next node location by stepsize
    if (step == 1)
        {
            //count = 0;
            return n;
        }
    next_node(n->next,(step-1));
}

void setvalue(int array_copy[], int i, int n)
{
    int j,p;

    for(j = 2; (i*j) <= n ; j++)
    {
        p = i*j;
        array_copy[p] = 1;
    }
}


int main(){
    //freopen("in.txt","r",stdin);
    node *current,*update_next,*head,*temp;
    int i,k,human_c,j=0,flag=0;
    //scanf("%d",&testcase);    // input testcases

    //start prime number selection by algo -> Sieve of Eratosthenes
    int n,l=0;
    //scanf("%i",&n);
    n=3502;


    int prime_array[1000];
    int array[n];
    for (i = 1; i <= n; i++)      // initialize all value of the array to 0
    {
        array[i] = 0;
    }

    for( i = 2; i < n; i++)
    {
        setvalue(array,i,n);     // set value 0 to its muliple cases
    }
    for(i = 2; i <= n; i++)
    {
        if(array[i] == 0)       // find the value which is 0 and record it in an array naming prime_array[]
        {
            //printf("%i ",i );
            prime_array[l] = i; 
            l++;
        }

    }

    /*for ( i = 0; i <= l ; i++)
    {
        printf("%i\n",prime_array[i] );
    }   */              
    // end prime number selection

    for( k = 1;; k++ )
    {   
        //scanf("%i",&num_state); 

        scanf("%i",&human_c);       // scan the number of nodes

        /*if(num_state < 13 || num_state > 100)                 // limit is 13 <= N <= 100 
            return 1;

        if(num_state == 13)                                   // state 13 gives 1...we knew that so we didn't compute
        {
            printf("%i\n",1 );
            continue;
        }*/
        if(human_c == 0)                                     // a'0' input finishes it
            return 0;
        //count = 0;


        node *first_node = create(1);           // create first node with node.number 1

        node *last_node = create(human_c);      // create last node with node.number = number of people 

        node *a[human_c];                       // decare a node type array

        a[0]=NULL;                              // keep a[0] out of it
        a[1] = first_node;                      // assign a[1] the first node
        a[human_c] = last_node;                 // assign a[number of people] the last node

        a[1]->previous = last_node;             // link a[1] with previous

        a[human_c]->next = first_node;          // link a[number of people] with the first node 


        for(i = 2; i < human_c;i++){            // create nodes from 2 to (number of people-1)
            a[i] = create(i);

        }
        for(i= 2; i < human_c;i++){             //assign previous and next nodes for 2 to (number of people-1)
            a[i]->next = a[i+1] ;
            a[i]->previous = a[i-1];
        }
        a[1]->next = a[2];                      //link a[1] with next node a[2]
        a[human_c]->previous = a[human_c-1];    //link (last node)a[number of people] with the previous a[number of people-1]


        head = a[1];                            //assign head or start position
        flag = 0;
        i = 0;                              //set flag for the first node

        do{

            if (flag == 0)
                {
                    current = next_node(head,prime_array[i]);           // evaluate next position for head node or start node only saving in "current" node
                    temp = current->previous;                   // keep the previous node for manipulation
                    temp->next = current->next;                 // set node.next for the previous node to the next of the current node  
                    update_next = current->next;                // keep the next node for manipulationk 
                    update_next->previous = temp;               // set node.previous for the next node which is update_next to the address of the previous of the current node which is temp
                    //head->next = current -> next;
                    flag = 1;
                    i++; 
                }
            else
                {
                    current = next_node(update_next,prime_array[i]);    // evaluate next position for rest of the nodes 
                    temp = current->previous;                   // keep the previous node for manipulation 
                    temp->next = current->next;                 // set node.next for the previous node to the next of the current node  
                    update_next = current->next;                // keep the next node for manipulationk 
                    update_next->previous = temp;               // set node.previous for the next node which is update_next to the address of the previous of the current node which is temp
                    //update_next->next = current->next;
                    i++;
                }


            //update_next->previous = current->previous;

            kill(current);                                      // kill the newly found position
            count++;                                            // take a record of the total kill

            //node *current = next_node(update_next,step_c);

        }while((human_c-count) > 1);                            // keep the killing spree unit there is only one person left

        for ( i = 1; i <= human_c; i++)
        {
            if(a[i]->number)                                    // check if any node is alive which means anynode has a node.number higher than 0
            {
                //printf("Case %d: ",k );
                printf("%i\n",a[i]->number );

            }
        }

        for ( i = 1; i <= human_c; i++){                        // free the allocated space on heap
            free(a[i]);
        }
        count = 0;                                              // set total kill to 0 as new testcase might start

    }
    return 0;
}

它适用于值490,但它在491上给出了分段错误。为什么?

问题的链接是https://www.urionlinejudge.com.br/judge/en/problems/view/1032

2 个答案:

答案 0 :(得分:1)

如果next_node()不等于1,则

steps不会返回任何值。

你的编译器可能已经警告过你了,顺便说一句。

答案 1 :(得分:1)

main()setvalue()中的索引超出array[]的范围

void setvalue(int array_copy[], int i, int n)
{
    ...

    for(j = 2; (i*j) <= n ; j++)
    {
        p = i*j;
        array_copy[p] = 1;       // ERROR: out of bounds when (i*j) == n
    }
}

int main()
{
    ...

    n=3502;
    ...
    int array[n];
    ...
    for (i = 1; i <= n; i++)
    {
        array[i] = 0;            // ERROR: out of bounds when i == n
    }

    for( i = 2; i < n; i++)
    {
        setvalue(array,i,n);
    }        

    for(i = 2; i <= n; i++)
    {
        if(array[i] == 0)        // ERROR: out of bounds when i == n
        ...
    }
相关问题