【问题标题】:Segmentation fault while allocating memory for front element of a queue in C为C中队列的前元素分配内存时出现分段错误
【发布时间】:2016-06-21 05:33:17
【问题描述】:

我在文件 queue.h 中有节点和队列结构

#ifndef QUEUE_H
#define QUEUE_H

#include<stdio.h>
#include<stdbool.h>

typedef struct rcb
{
    int seq_no;     
    int file_desc;   
    FILE *fp;      
    long sent;      
    long sizeOfFile;
    char *request_http_method;
    char *request_file;
    char *request_http_version;
    int level;         
    bool is_new_created;
    int remaining;
}* RCB;    

/*
 * Node of the queue.
 */
typedef struct node {
    RCB info;       //Data of each node.
    struct node *ptr;//pointer to the next node.
} * Node;

/*
 * Queue for the requests.
 */
typedef struct req_queue {
    Node front;     //front node.
    Node rear;      //rear node.
    int size;       //size of the queue.
} * Queue;


/**
 * Create the queue.
 */
void create(Queue queue);


/**
 * For inserting an item to the queue in sorted order of file size.
 * @param data
 */
void enque_SJF(Queue queue, RCB data);

#endif

queue.c

 #include "queue.h"

Node temp, front1;
int count = 0;    

/**
 * For creating the queue.
 */
void create(Queue queue) {
    queue->front = queue->rear = NULL;
    queue->size=0;
}

/**
 * Enqueing in the order of increasing file size.
 * @param data
 */
void enque_SJF(Queue que, RCB data) {
    bool found = false;
    Node temp = que->front;
    while (!found) {
        if (que->front == NULL) { //if the queue is empty.
            que->front = malloc(sizeof (struct node));
            que->front->ptr = NULL;
            que->front->info = data;
            que->rear = que->front;
            break;
        } else {
            if (temp->ptr == NULL) { 
                Node newnode = (struct node *) malloc(1 * sizeof (struct node));
                newnode->info = data;
                if (temp->info->sizeOfFile >= data->sizeOfFile) { 
                    newnode->ptr = temp;
                    que->front = newnode;
                    break;
                } else { //else enqueue at the rear.
                    temp->ptr = newnode;
                }
            } else {
                if (temp == que->front && temp->info->sizeOfFile >= data->sizeOfFile) { 
                    Node newnode = (struct node *) malloc(1 * sizeof (struct node));
                    newnode->info = data;
                    newnode->ptr = temp;
                    que->front = newnode;
                    break;
                }

                if (temp->ptr->info->sizeOfFile >= data->sizeOfFile) { 
                    Node newnode = (struct node *) malloc(1 * sizeof (struct node));
                    newnode->info = data;
                    newnode->ptr = temp->ptr;
                    temp->ptr = newnode;
                    break;
                } else
                    temp = temp->ptr;
            }
        }
    }
    que->size++;
}

我正在尝试将一个新节点排入 queue.c 文件中函数 enque_SJF 中的队列。 enqueue 函数在 sws.c 中由函数 serve_client 函数调用。这是 sws.c 这些文件中还有一些函数,但它们与我的问题无关,所以我没有将所有函数都写得更简单;

#include "Queue.h"
#include "network.h"
#include "schedulers.h"
#include "shared.h"

char scheduler[4];
pthread_t tid[2];
int port;
Queue req_queue;
bool flag[2];
int turn;
int sequence_number;


void  *serve_client()
{
    static char *buffer;                              /* request buffer */
    int fd;    

    req_queue = (struct req_queue *) malloc( sizeof (struct req_queue));
    create(req_queue);

    if (port != 0)
    {
        network_init( port );                             /* init network module */
        fprintf(stderr, "Connection port %d\n", port);
        for( ;; )
            /* main loop */
        {
            network_wait();
            if( !buffer )                                     /* 1st time, alloc buffer */
            {
                buffer = malloc( MAX_HTTP_SIZE );
                if( !buffer )                                   /* error check */
                {
                    perror( "Error while allocating memory" );
                    abort();
                }
            }

            for( fd = network_open(); fd >= 0; fd = network_open() )   /* get clients */
            {
                memset( buffer, 0, MAX_HTTP_SIZE );
                if( read( fd, buffer, MAX_HTTP_SIZE ) <= 0 )      /* read req from client */
                {
                    perror( "Error while reading request" );
                    abort();
                }
                printf("file path %s\n",buffer);
                //Initializing memory for the job.
                RCB request = (RCB) malloc(1 * sizeof (struct rcb));

                //breaking the request in appropriate format.
                request-> request_http_method = strtok(buffer, " "); //request method.
                request->request_file   = strtok(NULL, " /"); //request file
                request->request_http_version = strtok(NULL, "\n"); //HTTP version
                request->file_desc = fd;
                request->level = 1; // for multilevel scheduler.
                request->seq_no = sequence_number;
                sequence_number++; //increment global counter.


                    enque_SJF(req_queue, request); //Enqueue for Shortest Job First.


            }
        }
    }
    return 0;
}


bool isValidRequest(RCB request)
{

    // the request is parsed and checked the validity
}


void *SJF( )
{
   // function implemented
}




int main(int argc, char **argv )
{
    //default port, if no port is supplied.
    /* check for and process parameters
    */
    if( ( argc < 3 ) || ( sscanf( argv[1], "%d", &port ) < 1 ) || ( sscanf( argv[2], "%s", scheduler ) < 1 ) )
    {
        printf("port %d\n",port);
        printf("port %s\n",scheduler);
        printf( "usage: sms <port> <scheduler>\n" );
        return 0;
    }
    sequence_number = 1; //counter for number of requests.
    if (argc == 3)
    {
        port = atoi(argv[1]);
    }
     printf("port %d\n",port);
    pthread_create(&(tid[0]), NULL, serve_client, NULL);

    if(strcmp(scheduler,"SJF") ==0)
    {
        pthread_create(&(tid[1]), NULL, SJF, NULL);
    }
    else if(strcmp(scheduler,"RR")==0)
    {
        pthread_create(&(tid[1]), NULL, Round_Robin, NULL);
    }
    else if(strcmp(scheduler,"MLFB")==0)
    {
        pthread_create(&(tid[1]), NULL, MultilevelQueueWithFeedback, NULL);
    }
    else
    {
        printf("Scheduler Algorithm is not defined. Please enter one of them; SJF, RR, MLFB");
        return 0;
    }

    pthread_join(tid[0], NULL);
    pthread_join(tid[1], NULL);


    return 0;


}

在将新节点添加到队列时,我在以下行收到分段错误错误;

que->front->ptr = NULL;

在调试时,我看到分配内存后 que->front 的地址仍然是 0x0。有什么建议为什么它不分配内存?

【问题讨论】:

  • 请不要键入定义指针。
  • 检查malloc()是否成功。
  • 演员讨论真的够了。该帖子中的任何内容都只是一种意见
  • 在您的 serve_client() 函数中,当您填写 request 时,您将许多成员设置为指向 buffer 的指针(通过 strtok()),而不是复制相关的字符串。下次您擦除或填充 buffer 时,这些指针指向的数据将不再有效,因为您将覆盖它。

标签: c segmentation-fault queue dynamic-memory-allocation


【解决方案1】:

这就是为什么您应该始终对调用的函数执行成功检查。

如果malloc()失败,它将返回一个NULL指针,该指针存储在que-&gt;front中。之后,如果您尝试访问,则无需 NULL 检查

 que->front->ptr

您将取消引用调用undefined behaviorNULL 指针(即访问无效 内存)。

始终对 malloc() 的返回值进行 NULL 检查。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-26
    • 1970-01-01
    • 2016-11-28
    • 1970-01-01
    • 2020-11-15
    • 1970-01-01
    • 1970-01-01
    • 2014-04-02
    相关资源
    最近更新 更多