Thread: Memory not allocated??

  1. #1
    Registered User
    Join Date
    Jul 2003
    Posts
    15

    Memory not allocated??

    Thanks for your help in advance ^^

    Ok, my problem is that every time I run the program I get a Segmentation Fault... I think it's because the memory isn't allocating properly, could someone please take a look? Thanks <3

    Queue.h
    Code:
    #include <stdio.h>
    #include <string.h>
    
    typedef struct node Node;
    typedef struct queue Queue;
    
    struct node
    {
    	char *process;
    	struct node *next;
    };
    
    struct queue
    {
    	struct node *head;
    	struct node *tail;
    };
    
    Node* newNode(char* p);
    Queue* newQueue(Queue *q);
    void printQueue(Queue *q);
    void enqueue(Queue *q, char *p);
    char* dequeue(Queue *q);
    Queue* newStack(Queue *q);
    void push(Queue *q, char *p);
    char* pop(Queue *q);
    Queue.c
    Code:
    #include "Queue.h"
    #include <stdio.h>
    #include <string.h>
    
    Node* newNode(char* p)
    {
    	Node *n = (Node*)malloc(sizeof(int[10]));
    	n->process = p;
    	n->next = NULL;
    	return n;
    }
    
    Queue* newQueue(Queue *q)
    {
    	q = (Queue*)malloc(sizeof(int[10]));
    	q->head = NULL;
    	q->tail = NULL;
    	return q;
    }
    
    Queue* newStack(Queue *q)
    {
    	q = (Queue*)malloc(sizeof(int[10]));
    	Node *n = newNode("IDLE");
    	q->head = n;
    	return q;
    }
    
    void printQueue(Queue *q)
    {
    	Node *p; 
    	p = q->head;
    
    	for(p; p != NULL; p = p->next)
    		printf("%s ", p->process);
    
    	printf("\n");
    }
    
    void enqueue(Queue *q, char *p)
    {
    	Node *temp;
    	temp = newNode(p);
    	
    	if(q->head == NULL)
    	{
    		q->head = temp;
    		q->tail = q->head;
    		return;
    	}
    
    	else if(q->head == q->tail)
    	{
    		q->tail = temp;
    		q->head->next = q->tail;
    		return;
    	}
    
    	q->tail->next = temp;
    	q->tail = q->tail->next;
    }
    
    char* dequeue(Queue *q)
    {
    	char *r;
    
    	if(q->head == NULL)
    		return NULL;
    
    	if(q->head == q->tail)
    	{
    		r = q->head->process;
    		q->head->process = NULL;
    		q->head->next = NULL;
    		q->tail = q->head;
    		return r;
    	}
    
    	r = q->head->process;
    	q->head = q->head->next;
    	return r;
    }	
    
    void push(Queue *q, char *p)
    {
    	Node *n = newNode(p);
    	n->next = q->head;
    	q->head = n;
    }
    
    char* pop(Queue *q)
    {
    	char *temp = q->head->process;	
    
    	if(q->head->next == NULL)
    		return temp;
    
    	q->head = q->head->next;
    	return temp;
    }	
    /*
    int main()
    {
    	Queue *q; Node *n;
    	q = newQueue(q);
    	
    	printQueue(q);
    	enqueue(q, "A");
    	printQueue(q);
    	enqueue(q, "B");
    	printQueue(q);
    	enqueue(q, "C");	
    	printQueue(q);
    	enqueue(q, "D");
    	printQueue(q);
    
    	dequeue(q);
    	printQueue(q);
    	dequeue(q);
    	printQueue(q);
    
    	printf("\n\n\n");
    
    	Queue *s = newStack(s);
    
    	printQueue(s);
    	push(s, "A");
    	printQueue(s);
    	push(s, "B");
    	printQueue(s);
    	pop(s);
    	printQueue(s);
    	pop(s);
    	printQueue(s);
    	pop(s);
    	printQueue(s);
    
    }
    
    
    */
    main.c
    Code:
    #include "Queue.h"
    #include <stdio.h>
    #include <string.h>
    
    typedef struct cpu CPU;
    
    struct cpu
    {
    	struct queue *Running;
    	struct queue *Ready;
    	struct queue *Waiting;	
    };
    
    CPU* newCPU(CPU *c)
    {
    	c = (CPU*)malloc(sizeof(int[10]));
    	
    	c->Running = newStack(c->Running);
    	c->Ready = newQueue(c->Ready);
    	c->Waiting = newQueue(c->Waiting);
    }
    
    void event1(CPU *cpu)
    {
    	printf("**Event 1 Occurs\n");
    
    	// if nothing in Ready queue, process remains in Running Queue
    	if (cpu->Ready->head != NULL)	
    	{
    		// Moves the running Process to the Ready Queue
    		enqueue(cpu->Ready, pop(cpu->Running));	
    	}
    
    	// Moves head of Ready Queue to the Running Stack
    	push(cpu->Running, dequeue(cpu->Ready));	
    }
    
    void event2(CPU *cpu)
    {
    	printf("**Event 2 Occurs\n");
    
    	// Running process goes to Waiting Queue
    	enqueue(cpu->Waiting, pop(cpu->Running));
    
    	// Moves head of Ready Queue to the Running Stack
    	push(cpu->Running, dequeue(cpu->Ready));
    }
    
    void event3(CPU *cpu)
    {
    	printf("**Event 3 Occurs\n");
    
    	// If Ready Queue is empty and Running state is in IDLE
    	if (cpu->Running->head == NULL && cpu->Ready->head == NULL)
    		push(cpu->Running, dequeue(cpu->Waiting));
    
    	// Waiting Process goes to Ready state
    	enqueue(cpu->Ready, dequeue(cpu->Waiting));
    }
    
    CPU* initialize(CPU *cpu)
    {
    	push(cpu->Running, "1");
    	
    	enqueue(cpu->Ready, "5");
    	enqueue(cpu->Ready, "4");
    	enqueue(cpu->Ready, "3");
    	enqueue(cpu->Ready, "2");
    
    	enqueue(cpu->Waiting, "6");
    	enqueue(cpu->Waiting, "7");
    	enqueue(cpu->Waiting, "8");
    	enqueue(cpu->Waiting, "9");
    
    	return cpu;
    }
    
    void printCPU(CPU *cpu)
    {
    
    	printf("\n**Print CPU **\nRunning: ");
    	printQueue(cpu->Running);
    	printf("Ready: ");
    	printQueue(cpu->Ready);
    	printf("Waiting: ");
    	printQueue(cpu->Waiting);
    }
    
    int main()
    {
    
    	CPU *cpu = newCPU(cpu);
    	printf("%s\n", cpu->Running->head->process);
    
    //	printCPU(cpu);
    //	initialize(cpu);
    }

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    There are a few points here:
    Code:
    #include "Queue.h"
    #include <stdio.h>
    #include <string.h>
    You usually want your personal includes after the standard includes. Also, you include both of these in your header file, so they're getting included twice. Since your header doesn't actually use any of the functions in either of those libraries, remove the includes from Queue.h.

    Code:
    Node *n = (Node*)malloc(sizeof(int[10]));
    Next, stop typcasting malloc. If it gives you warnings when you don't, then stop compiling as C++ and compile as C. If it still gives you warnings, then it means you're missing the header it belongs in. You aren't, so it shouldn't give you warnings. If it does, you're compiling as C++.

    Code:
    q = (Queue*)malloc(sizeof(int[10]));
    Danger! Danger Will Robinson!
    Look closely at what you are doing:
    Code:
    typedef struct queue Queue;
    ...
    Queue* newQueue(Queue *q)
    {
    	q = (Queue*)malloc(sizeof(int[10]));
    	q->head = NULL;
    	q->tail = NULL;
    	return q;
    }
    See the problem? Well actually there are many.

    1) You're mallocing space for ten integers when in reality you should be allocating space for one Queue.
    2) If it were correct, the usual way to allocate space for ten integers is like so:

    foo = malloc( sizeof( int ) * 10 );

    3) The only way 'q' will be actually updated to point at what you allocate is if you call it like this:

    Queue *ptr;
    ptr = newQueue( ptr );

    If you call it like this:

    Queue *ptr1, *ptr2;

    ptr2 = newQueue( ptr1 );

    Then only ptr2 is actually ends up pointing at what you want it to, assuming the rest of the code were correct.

    So in reality, there is no point in having any arguments to your newQueue function. Just declare 'q' as a local pointer, malloc, initialize, and return.

    Your "newStack" has the exact same problems as "newQueue". Why are you mallocing 10 integers? Malloc structures, after all, that's what you're trying to create.

    This:
    Code:
    void printQueue(Queue *q)
    {
    	Node *p; 
    	p = q->head;
    
    	for(p; p != NULL; p = p->next)
    Could be shortened to:
    Code:
    void printQueue( Queue *q )
    {
        Node *p;
    
        for( p = q->head; p; p = p->next )
        ...stuff...
    That will get you started. Fix your malloc problems and that'll help a great deal as to making your program stable.

    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Jul 2003
    Posts
    15
    Thanks for your help ^^

    But, the problems you mentioned are ones that I was already aware of... you see, I had the changes implemented in my orginal code (the p = malloc(sizeof(Queue)); )

    I went to the learning center at my university and they said to try the changes that you see now... and it -still- doesn't work -- i'll change it back but is there any more suggestions? I still think it has something to do with memory allocation, although I have no idea what =/

  4. #4
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    >but is there any more suggestions?

    How about something like this?
    Code:
    Node* newNode(char* p)
    {
       Node *n = malloc(sizeof(*n));
       if(n)
       {
          n->process = malloc(strlen(p) + 1);
          if(!n->process)
          {
             free(n);
             return NULL;
          }
          strcpy(n->process, p);
          n->next = NULL;
       }
       return n;
    }
    Check return values!

    The following is not C90.
    Code:
    Queue* newStack(Queue *q)
    {
    	q = (Queue*)malloc(sizeof(int[10]));
    	Node *n = newNode("IDLE");
    	q->head = n;
    	return q;
    }
    [edit]
    And this.
    Code:
    CPU* newCPU(CPU *c)
    {
       c = malloc(sizeof(*c));
       if(c)
       {
          c->Running = newStack(c->Running);
          c->Ready   = newQueue(c->Ready);
          c->Waiting = newQueue(c->Waiting);
       }
       return c;
    }
    [/edit]
    Last edited by Dave_Sinkula; 09-23-2003 at 02:37 PM.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  5. #5
    Registered User
    Join Date
    Jul 2003
    Posts
    15
    If anyone is curious.... I solved the problem. ^^;

    Code:
    CPU* newCPU(CPU *c)
    {
    	c = (CPU*)malloc(sizeof(int[10]));
    	
    	c->Running = newStack(c->Running);
    	c->Ready = newQueue(c->Ready);
    	c->Waiting = newQueue(c->Waiting);
    }
    this section of code is missing a return statement, and therefore everytime I tried to use a CPU object I was getting a segmentation fault because there is no memory allocated etc. bleh bleh *stupid me* ^^

    Thanks so much for your help though!

  6. #6
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >>this section of code is missing a return statement,
    Sounds like you need to up the warning level on your compiler
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  7. #7
    Registered User
    Join Date
    Jul 2003
    Posts
    15
    Unfortunatly, I can't do that because I log on the University's unix server and we use the gcc compiler =/

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Originally posted by Alexisa
    Unfortunatly, I can't do that because I log on the University's unix server and we use the gcc compiler =/
    Yeah so?

    gcc -Wall -c myprog myprog.c

    An example.

    Quzah.
    Hope is the first step on the road to disappointment.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Mutex and Shared Memory Segment Questions.
    By MadDog in forum Linux Programming
    Replies: 14
    Last Post: 06-20-2010, 04:04 AM
  2. Check if there is memory allocated
    By The Wazaa in forum C++ Programming
    Replies: 3
    Last Post: 04-23-2006, 05:48 AM
  3. [C++/WinAPI] Checking number of allocated memory
    By jagi in forum C++ Programming
    Replies: 2
    Last Post: 03-28-2005, 06:10 PM
  4. Memory handler
    By Dr. Bebop in forum C Programming
    Replies: 7
    Last Post: 09-15-2002, 04:14 PM
  5. deleting dynamically allocated memory...
    By heljy in forum C++ Programming
    Replies: 2
    Last Post: 09-08-2002, 11:40 AM