Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Remving an element from Queue
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  Messages 1 - 25 of 39 - Collapse all  -  Translate all to Translated (View all originals)   Newer >
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
arnuld  
View profile  
 More options May 8 2012, 4:09 am
Newsgroups: comp.lang.c
From: arnuld <sunr...@invalid.address>
Date: 08 May 2012 08:09:39 GMT
Local: Tues, May 8 2012 4:09 am
Subject: Remving an element from Queue
WANTED: Removing all elements matching a particular key from a Queue
WHAT I GOT: Segfault
WANTED: Segfaults in removeAllMatches().  I think routine/fucntion is too
complex to be understood. removeAllMatches(arg1, arg2) is supposed to
remove all elements from arg1 which match value of arg2.

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

struct myStruct
{
  int num;
  struct myStruct* next;

};

struct myQueue
{
  struct myStruct* head;
  struct myStruct* tail;

};

int enqueue(struct myQueue* q, int n);
int dequeue(struct myQueue* q);

struct myQueue* newQueue(void);
void makeNull(struct myQueue* q);
void removeAllMatches(struct myQueue* q, const int num);

void printQueue(struct myQueue* q);
void printStruct(struct myStruct* p);

int main(void)
{
  struct myQueue* q = newQueue();
  printQueue(q);

  enqueue(q, -1);
  enqueue(q, 100);
  enqueue(q, 38);
  enqueue(q, 100);
  enqueue(q, 38);
  enqueue(q, 9);
  enqueue(q, 100);
  printQueue(q);

  removeAllMatches(q, 100);
  printQueue(q);
  /*  makeNull(q);
      printQueue(q); */
  free(q);
  q = NULL;

  return 0;

}

int enqueue(struct myQueue* q, int n)
{
  int ret;
  if(NULL == q)
    {
      printf("Invalid Args\n");
      ret = -1;
    }
  else
    {
      struct myStruct* p = malloc(1 * sizeof *p);
      if(NULL == p)
        {
          printf("Out of memory\n");
          exit(EXIT_FAILURE);
        }

      p->num = n;
      p->next = NULL;
      if(NULL == q->tail && NULL == q->head)
        {
          printf("Empty Queue, Adding first element\n");
          q->head = q->tail = p;
          ret = 0;
        }
      else if(NULL == q->tail || NULL == q->head)
        {
          printf("IN: %s @%d; ", __func__, __LINE__);
          printf("There is something seriously wrong with head/tail
assignment of your Queue\n");
          free(p);
          ret = 1;
        }
      else
        {
          printf("Adding Element\n");
          q->tail->next = p;
          q->tail = p;
          ret = 0;
        }
    }

  return ret;

}

int dequeue(struct myQueue* q)
{
  int ret = -1;
  if(NULL == q)
    {
      printf("Invalid Args\n");
      ret = -1;
    }
  else
    {
      struct myStruct* h;
      if(NULL == q->head && NULL == q->tail)
        {
          printf("Queue is already empty\n");
          ret = 0;
        }
      else if(NULL == q->head || NULL == q->tail)
        {
          printf("IN: %s @%d; ", __func__, __LINE__);
          printf("There is something seriously wrong with head/tail
assignment of your Queue\n");
          ret = 1;
        }
      else
        {
          h = q->head;
          q->head = q->head->next;
          free(h);
          if(NULL == q->head)
            {
              printf("Removing Last element left\n");
              q->head = q->tail = NULL;
            }
          else
            {
              printf("Removing Some element\n");
            }
          ret = 0;
        }
    }

  return ret;

}

/* Added many months later */
void removeAllMatches(struct myQueue* q, const int num)
{
  if(NULL == q)
    {
      printf("Invalid Args\n");
      return;
    }

  if(NULL == q->head && NULL == q->tail)
    {
      printf("Queue is already empty\n");
    }
  else if(NULL == q->head || NULL == q->tail)
    {
      printf("IN: %s @%d; ", __func__, __LINE__);
      printf("There is something seriously wrong with head/tail
assignment of your Queue\n");
      exit(EXIT_FAILURE);
    }
  else
    {
      struct myStruct *p, *d, *h;
      p = d = h = NULL;
      for(h = q->head; h; h = h->next)
        {
          d = h;
          if(num == d->num)
            {
              if(num == q->head->num )
                {
                  q->head = q->head->next;
                }

              if(num == q->tail->num)
                {
                  q->tail = q->tail->next;
                }

              if(p)
                {
                  p->next = h->next;
                }
              free(d);
            }
          else
            {
              p = h;
            }
        }

    }

}

void makeNull(struct myQueue* q)
{
  if(q)
    {
      while(q->head) dequeue(q);
    }

}

struct myQueue* newQueue(void)
{
  struct myQueue* p = malloc(1 * sizeof *p);
  if(NULL == p)
    {
      printf("Out of Memory\n");
      exit(EXIT_FAILURE);
    }

  return p;

}

void printQueue(struct myQueue* q)
{
  if(q)
    {
      struct myStruct* p = q->head;
      for(; p; p = p->next)  printStruct(p);
      printf("-----------------------------------------\n");
    }

}

void printStruct(struct myStruct* p)
{
  if(p)
    {
      printf("title: %d\n", p->num);
    }

}

======================== OUTPUT ==========================
[arnuld@dune C]$ gcc -ansi -pedantic -Wall -Wextra Queue.c
[arnuld@dune C]$ ./a.out
-----------------------------------------
Empty Queue, Adding first element
Adding Element
Adding Element
Adding Element
Adding Element
Adding Element
Adding Element
title: -1
title: 100
title: 38
title: 100
title: 38
title: 9
title: 100
-----------------------------------------
Segmentation fault
[arnuld@dune C]$

--
 arnuld
http://LispMachine.Wordpress.com


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Eric Sosman  
View profile  
 More options May 8 2012, 8:01 am
Newsgroups: comp.lang.c
From: Eric Sosman <esos...@ieee-dot-org.invalid>
Date: Tue, 08 May 2012 08:01:26 -0400
Local: Tues, May 8 2012 8:01 am
Subject: Re: Remving an element from Queue
On 5/8/2012 4:09 AM, arnuld wrote:

> WANTED: [...]

     I've only skimmed your code, but this bit is obviously wrong:

> struct myQueue* newQueue(void)
> {
>    struct myQueue* p = malloc(1 * sizeof *p);
>    if(NULL == p)
>      {
>        printf("Out of Memory\n");
>        exit(EXIT_FAILURE);
>      }

>    return p;
> }

     Hint: What are the values of the elements in the newly-allocated
struct?

--
Eric Sosman
esos...@ieee-dot-org.invalid


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
nick_keighley_nos...@hotmail.com  
View profile  
 More options May 8 2012, 8:09 am
Newsgroups: comp.lang.c
From: nick_keighley_nos...@hotmail.com
Date: Tue, 8 May 2012 05:09:09 -0700 (PDT)
Local: Tues, May 8 2012 8:09 am
Subject: Re: Remving an element from Queue

On Tuesday, May 8, 2012 9:09:39 AM UTC+1, arnuld wrote:
> WANTED: Removing all elements matching a particular key from a Queue
> WHAT I GOT: Segfault
> WANTED: Segfaults in removeAllMatches().  I think routine/fucntion is too
> complex to be understood. removeAllMatches(arg1, arg2) is supposed to
> remove all elements from arg1 which match value of arg2.

I don't get any output at all it crashes at the first printQueue() call in main(). The Head and Tail pointers contain crap (0xcdcdcd on a Microsoft system). They contain crap because newQueue() doesn't initialise them.

Why didn't you use a debugger? That's how I found the bug.

<code>
[...]

what are head and tail at this point?

> }

> void printQueue(struct myQueue* q)
> {
>   if(q)
>     {
>       struct myStruct* p = q->head;

oops!

>       for(; p; p = p->next)  printStruct(p);
>       printf("-----------------------------------------\n");
>     }
> }

</code>

you could tidy things up by factoring out your queue check code that appears in at least three places

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
BartC  
View profile  
 More options May 8 2012, 9:03 am
Newsgroups: comp.lang.c
From: "BartC" <b...@freeuk.com>
Date: Tue, 8 May 2012 14:03:48 +0100
Local: Tues, May 8 2012 9:03 am
Subject: Re: Remving an element from Queue

<nick_keighley_nos...@hotmail.com> wrote in message

news:27603720.623.1336478949976.JavaMail.geo-discussion-forums@vbcm9...

> On Tuesday, May 8, 2012 9:09:39 AM UTC+1, arnuld wrote:

>> WANTED: Removing all elements matching a particular key from a Queue
>> WHAT I GOT: Segfault
>> WANTED: Segfaults in removeAllMatches().  I think routine/fucntion is too
>> complex to be understood. removeAllMatches(arg1, arg2) is supposed to
>> remove all elements from arg1 which match value of arg2.

> I don't get any output at all it crashes at the first printQueue() call in
> main(). The Head and Tail pointers contain crap (0xcdcdcd on a Microsoft
> system). They contain crap because newQueue() doesn't initialise them.
> Why didn't you use a debugger? That's how I found the bug.

Mine just prints forever on printQueue(). Looking at newQueue() instantly
reveals the problem.

No need for any debugger. And what exactly did it say anyway?

--
Bartc


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Mark Bluemel  
View profile  
 More options May 8 2012, 9:07 am
Newsgroups: comp.lang.c
From: Mark Bluemel <mark.blue...@googlemail.com>
Date: Tue, 8 May 2012 06:07:41 -0700 (PDT)
Local: Tues, May 8 2012 9:07 am
Subject: Re: Remving an element from Queue
On May 8, 9:09 am, arnuld <sunr...@invalid.address> wrote:

You need to stop coding and start thinking...

I don't know what's wrong with your code (though I have strong
suspicions about the code which tries to do some special casing for
start and end of list), but if I could be bothered to investigate I'd
probably do the old "paper computer" exercise...

On a largish sheet of paper I'd draw the structure of my linked list
at the point that the removeAll function was invoked, with a box
representing each entry of the list, with the forward and back
pointers and the value stored.

I'd then draw boxes for p, d and h (horrid names for variables) and
walk through the code updating all the boxes as I went.

I don't know why you keep repeating your checking code rather than
extracting it to a "sanity_check" function. I also don't know why you
don't have a function for "remove the current entry" from the list,
but you seem to be making a big deal out of a fairly small exercise.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Mark Bluemel  
View profile  
 More options May 8 2012, 9:35 am
Newsgroups: comp.lang.c
From: Mark Bluemel <mark.blue...@googlemail.com>
Date: Tue, 8 May 2012 06:35:30 -0700 (PDT)
Local: Tues, May 8 2012 9:35 am
Subject: Re: Remving an element from Queue
On May 8, 9:09 am, arnuld <sunr...@invalid.address> wrote:

Are you sure?

>                 }

>               if(p)
>                 {
>                   p->next = h->next;
>                 }
>               free(d);
>             }

Your code seems messy here - how about this?

    struct myStruct *previous = NULL;
      struct myStruct *current;
      for(current = q->head; current; current = current->next) {
          if(num == current->num) {
              if(current == q->head) {
                q->head = q->head->next;
              }
              if(current == q->tail) {
                q->tail = previous;
              }
              if(previous) {
                previous->next = current->next;
              }
              free(current);
          }
          else {
            previous = current;
          }
      }


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Johann Klammer  
View profile  
 More options May 8 2012, 2:50 pm
Newsgroups: comp.lang.c
From: Johann Klammer <klamm...@NOSPAM.a1.net>
Date: Tue, 08 May 2012 20:50:26 +0200
Local: Tues, May 8 2012 2:50 pm
Subject: Re: Remving an element from Queue

arnuld wrote:

[SNIP]

another
BUG:
you free() the memory pointed to by d (which is the same as h),
and in the for statement you access it: h = h->next
retrieve the next pointer _before_ you free() the element.

perhaps you should use some library for that...
glib or glibc's <search.h> perhaps...

>        }
>      else
>        {
>          p = h;
>        }
>    }

>      }
> }

[SNIP]

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
arnuld  
View profile  
 More options May 9 2012, 1:43 am
Newsgroups: comp.lang.c
From: arnuld <sunr...@invalid.address>
Date: 09 May 2012 05:43:02 GMT
Local: Wed, May 9 2012 1:43 am
Subject: Re: Remving an element from Queue

> On Tue, 08 May 2012 08:01:26 -0400, Eric Sosman wrote:
>> On 5/8/2012 4:09 AM, arnuld wrote:
>      I've only skimmed your code, but this bit is obviously wrong:
>> struct myQueue* newQueue(void)
>> {
>>    struct myQueue* p = malloc(1 * sizeof *p); if(NULL == p)
>>      {
>>        printf("Out of Memory\n");
>>        exit(EXIT_FAILURE);
>>      }

>>    return p;
>> }
>      Hint: What are the values of the elements in the newly-allocated
> struct?

One needs to keep on practicing writing code and thinking about data
structures, else he forgets (like me). (Now, taking dequeue code from
other poster), is this fine now or still some bits are wrong:

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

enum { CODE_SUCC = 0, CODE_ERR = 1 };

struct myStruct
{
  int num;
  struct myStruct* next;

};

struct myQueue
{
  struct myStruct* head;
  struct myStruct* tail;

};

int enqueue(struct myQueue* q, int n);
int dequeue(struct myQueue* q);

struct myQueue* newQueue(void);
void makeNull(struct myQueue* q);
void removeAllMatches(struct myQueue* q, const int num);

void printQueue(struct myQueue* q);
void printStruct(struct myStruct* p);
int queue_sanity_check(struct myQueue* q);

int main(void)
{
  struct myQueue* q = newQueue();
  printQueue(q);

  enqueue(q, -1);
  enqueue(q, 100);
  enqueue(q, 38);
  enqueue(q, 100);
  enqueue(q, 38);
  enqueue(q, 9);
  enqueue(q, 100);
  printQueue(q);

  removeAllMatches(q, 100);
  printQueue(q);
  /*
  makeNull(q);
  printQueue(q);
  free(q);
  q = NULL;
  */
  return 0;

}

int enqueue(struct myQueue* q, int n)
{
  struct myStruct* p;
  if(CODE_ERR == queue_sanity_check(q))
    {
      printf("IN: %s @%d: Sanity Check failed\n", __func__, __LINE__);
      return CODE_ERR;
    }

  p = malloc(1 * sizeof *p);
  if(NULL == p)
    {
      printf("Out of memory\n");
      exit(EXIT_FAILURE);
    }

  p->num = n;
  p->next = NULL;

  if(NULL == q->tail && NULL == q->head)
    {
      printf("Empty Queue, Adding first element\n");
      q->head = q->tail = p;
    }
  else
    {
      printf("Adding Element to tail\n");
      q->tail->next = p;
      q->tail = p;
    }

  return CODE_SUCC;

}

int dequeue(struct myQueue* q)
{
  int ret = CODE_ERR;;

  if(CODE_ERR == queue_sanity_check(q))
    {
      ret = CODE_ERR;
    }

  else
    {
      struct myStruct* h;
      h = q->head;
      q->head = q->head->next;
      free(h);
      if(NULL == q->head)
        {
          printf("Removing Last element left\n");
          q->head = q->tail = NULL;
        }
      else
        {
          printf("Removing Some element\n");
        }

      ret = CODE_SUCC;
    }

  return ret;

}

/* Added many months later */
void removeAllMatches(struct myQueue* q, const int num)
{
  struct myStruct *previous, *current;
  if(CODE_ERR == queue_sanity_check(q))
    {
      return;
    }

  previous = NULL;

  for(current = q->head; current; current = current->next)
        {
          if(num == current->num)
            {
              if(num == q->head->num)
                {
                  q->head = q->head->next;
                }

              if(num == q->tail->num)
                {
                  q->tail = previous;
                }

              if(previous)
                {
                  previous->next = current->next;
                }

              free(current);
            }
          else
            {
              previous = current;
            }
        }

}

void makeNull(struct myQueue* q)
{
  if(q)
    {
      while(q->head) dequeue(q);
    }

}

struct myQueue* newQueue(void)
{
  struct myQueue* p = malloc(1 * sizeof *p);
  if(NULL == p)
    {
      printf("Out of Memory\n");
      exit(EXIT_FAILURE);
    }

  p->head = p->tail = NULL;

  return p;

}

void printQueue(struct myQueue* q)
{
  if(q)
    {
      struct myStruct* p = q->head;
      for(; p; p = p->next) printStruct(p);
      printf("-----------------------------------------\n");
    }

}

void printStruct(struct myStruct* p)
{
  if(p)
    {
      printf("title: %d\n", p->num);
    }

}

int queue_sanity_check(struct myQueue* q)
{
  int ret = CODE_ERR;
  if(NULL == q)
    {
      printf("Invalid Args\n");
      ret = CODE_ERR;
    }
  else if(NULL == q->head && NULL == q->tail)
    {
      printf("Queue is already empty\n");
      ret = CODE_SUCC;
    }
  else if(NULL == q->head || NULL == q->tail)
    {
      printf("IN: %s @%d; ", __func__, __LINE__);
      printf("There is something seriously wrong with head/tail
assignment of your Queue\n");
      exit(EXIT_FAILURE);
    }
  else
    {
      ret = CODE_SUCC;
    }

  return ret;

}

================ OUTPUT =====================
/home/arnuld/programs/C $ gcc -ansi -pedantic -Wall -Wextra Queue.c
/home/arnuld/programs/C $ ./a.out
-----------------------------------------
Queue is already empty
Empty Queue, Adding first element
Adding Element to tail
Adding Element to tail
Adding Element to tail
Adding Element to tail
Adding Element to tail
Adding Element to tail
title: -1
title: 100
title: 38
title: 100
title: 38
title: 9
title: 100
-----------------------------------------
title: -1
title: 38
title: 38
title: 9
-----------------------------------------
/home/arnuld/programs/C $

--
 arnuld
http://LispMachine.Wordpress.com


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Barry Schwarz  
View profile  
 More options May 9 2012, 2:21 am
Newsgroups: comp.lang.c
From: Barry Schwarz <schwa...@dqel.com>
Date: Tue, 08 May 2012 23:21:06 -0700
Local: Wed, May 9 2012 2:21 am
Subject: Re: Remving an element from Queue
On 09 May 2012 05:43:02 GMT, arnuld <sunr...@invalid.address> wrote:

snip

What is the point of multiplying by 1?

ret is already initialized to CODE_ERR.  

>    }

>  else
>    {
>      struct myStruct* h;
>      h = q->head;
>      q->head = q->head->next;

If q->head is NULL (the queue is empty), this invokes undefined
behavior.

>      free(h);
>      if(NULL == q->head)
>    {
>      printf("Removing Last element left\n");
>      q->head = q->tail = NULL;

You already know q->head is NULL.  

Assume the queue consists of nodes containing 2, 1, 3, 1 and num is 1.

>  for(current = q->head; current; current = current->next)

Whenever you free current in the loop, the third expression above
invokes undefined behavior on the next iteration.

>    {
>      if(num == current->num)

During iteration 1, this is false.

During iteration 2, this is true.

During iteration 3, this is false.

During iteration 4, this is true.

>        {
>          if(num == q->head->num)

During iteration 2, this is false.

During iteration 4, this is false.

>            {
>              q->head = q->head->next;
>            }

>          if(num == q->tail->num)

During iteration 2, this is true.

During iteration 4 this is false because q->tail points to node
containing 2.

>            {
>              q->tail = previous;

q->tail now points to node containing 2 which is same as q->head. Your
q is now broken.

I think the if test should be on the pointers, not on num:
     if (current = q->tail)

>            }

>          if(previous)

During iteration 2, this is true.

During iteration 4, this is true.

>            {
>              previous->next = current->next;

The node containing 2 now points to the node containing 3.

The node containing 3 now points to NULL.

>            }

>          free(current);
>        }
>      else
>        {
>          previous = current;

After iteration 1, previous points to node containing 2.

After iteration 2, previous still points to node containing 2.

After iteration 3, previous points to node containing 3.

After iteration 4, previous still points to node containing 3.

>        }
>    }
>}

Your queue consists of nodes containing 2 and 3 but q->head and
q->tail both point to the node containing 2.

>void makeNull(struct myQueue* q)
>{

Why do you not call queue_sanity_check here also?

Since you have managed to create the situation, you might also want to
add the following to the end of the if:
      || q->tail->next != NULL

This demonstrates you don't use q->tail so why bother maintaining it?

--
Remove del for email


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
nick_keighley_nos...@hotmail.com  
View profile  
 More options May 9 2012, 3:01 am
Newsgroups: comp.lang.c
From: nick_keighley_nos...@hotmail.com
Date: Wed, 9 May 2012 00:01:24 -0700 (PDT)
Local: Wed, May 9 2012 3:01 am
Subject: Re: Remving an element from Queue

and main()

> No need for any debugger. And what exactly did it say anyway?

well the program has Undefined Behaviour so the question isn't really meaningful. Visual C++ gives:-

"Unhandled exception at 0x00411cc9 in quick.exe: 0xC0000005: Access violation reading location 0xcdcdcdcd."

The debugger shows it crashed in printStruct() and p has an insane value.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
nick_keighley_nos...@hotmail.com  
View profile  
 More options May 9 2012, 3:03 am
Newsgroups: comp.lang.c
From: nick_keighley_nos...@hotmail.com
Date: Wed, 9 May 2012 00:03:07 -0700 (PDT)
Local: Wed, May 9 2012 3:03 am
Subject: Re: Remving an element from Queue

and main()

> No need for any debugger. And what exactly did it say anyway?

well the program has Undefined Behaviour so the question isn't really meaningful. Visual C++ gives:-

"Unhandled exception at 0x00411cc9 in quick.exe: 0xC0000005: Access violation reading location 0xcdcdcdcd."

The debugger shows it crashed in printStruct() and p has an insane value.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
arnuld  
View profile  
 More options May 9 2012, 5:27 am
Newsgroups: comp.lang.c
From: arnuld <sunr...@invalid.address>
Date: 09 May 2012 09:27:58 GMT
Local: Wed, May 9 2012 5:27 am
Subject: Re: Remving an element from Queue

> On Tue, 08 May 2012 23:21:06 -0700, Barry Schwarz wrote:
>> On 09 May 2012 05:43:02 GMT, arnuld <sunr...@invalid.address> wrote:
> ret is already initialized to CODE_ERR.

I know. I learned from someone here that assignment at initialization of
a variable is always a good idea. I see it solves problems for me (in
case of int types)

>>      struct myStruct* h;
>>      h = q->head;
>>      q->head = q->head->next;
> If q->head is NULL (the queue is empty), this invokes undefined
> behavior.

I have removed this in code I posted 2nd time.

>>      free(h);
>>      if(NULL == q->head)
>>        {
>>          printf("Removing Last element left\n"); q->head = q->tail =
> NULL;
> You already know q->head is NULL.

yeah. So, instead of s->head = s->tail = NULL, I could have used s->tail
= s->head. It was just a matter of style for me.

I am trying to understand rest of your comments

--
 arnuld
http://LispMachine.Wordpress.com


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
BartC  
View profile  
 More options May 9 2012, 5:37 am
Newsgroups: comp.lang.c
From: "BartC" <b...@freeuk.com>
Date: Wed, 9 May 2012 10:37:38 +0100
Local: Wed, May 9 2012 5:37 am
Subject: Re: Remving an element from Queue
<nick_keighley_nos...@hotmail.com> wrote in message

news:17230148.361.1336546987566.JavaMail.geo-discussion-forums@vbcm9...

As I said, when I tried it under one compiler, it just looped forever
p;rinting the same sequence of 3 or 4 values, so p (ie. q->head) presumably
had a sensible enough value.

Debuggers have their uses but are probably overkill for an obvious logic
error within the first dozen lines of execution!

When a program goes wrong a few billion statements from the start, because
of some unrelated code a billion or two statements back in a totally
different part, then it might be time to wheel it out (and even then I'm not
sure how they could help).

--
Bartc


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
arnuld  
View profile  
 More options May 9 2012, 5:44 am
Newsgroups: comp.lang.c
From: arnuld <sunr...@invalid.address>
Date: 09 May 2012 09:44:37 GMT
Local: Wed, May 9 2012 5:44 am
Subject: Re: Remving an element from Queue

> On Tue, 08 May 2012 05:09:09 -0700, nick_keighley_nospam wrote:
> ..SNIP...
> you could tidy things up by factoring out your queue check code that
> appears in at least three places

you are right. I did that and now after reading the analysis from Barry
Schwarz I can see that head/tail pointing at wrong places, so I should
make a check for that too ?  

No, unlike earlier now I think those checks will not save these
programming errors I am making. I better set pointers right rather than
spending my typing-energy to avoid/find errors.

--
 arnuld
http://LispMachine.Wordpress.com


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
nick_keighley_nos...@hotmail.com  
View profile  
 More options May 9 2012, 6:05 am
Newsgroups: comp.lang.c
From: nick_keighley_nos...@hotmail.com
Date: Wed, 9 May 2012 03:05:15 -0700 (PDT)
Local: Wed, May 9 2012 6:05 am
Subject: Re: Remving an element from Queue

On Wednesday, May 9, 2012 10:37:38 AM UTC+1, Bart wrote:
> <nick_keighley_nos...@hotmail.com> wrote in message
> news:17230148.361.1336546987566.JavaMail.geo-discussion-forums@vbcm9...
> > On Tuesday, May 8, 2012 2:03:48 PM UTC+1, Bart wrote:
> >> <nick_keighley_nos...@hotmail.com> wrote in message
> >> > Why didn't you use a debugger? That's how I found the bug.

<snip>

and how would I know the crash was going to occur within a few dozen lines of startup?

> When a program goes wrong a few billion statements from the start, because
> of some unrelated code a billion or two statements back in a totally
> different part, then it might be time to wheel it out (and even then I'm not
> sure how they could help).

whatever. I judged running under a debugger was a quicker way to find the bug than ploughing through lots of source code. It so happened it pin-pointed the bug almost instantly.

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
James Kuyper  
View profile  
 More options May 9 2012, 7:54 am
Newsgroups: comp.lang.c
From: James Kuyper <jameskuy...@verizon.net>
Date: Wed, 09 May 2012 07:54:35 -0400
Local: Wed, May 9 2012 7:54 am
Subject: Re: Remving an element from Queue
On 05/09/2012 05:27 AM, arnuld wrote:

>> On Tue, 08 May 2012 23:21:06 -0700, Barry Schwarz wrote:

>>> On 09 May 2012 05:43:02 GMT, arnuld <sunr...@invalid.address> wrote:

>> ret is already initialized to CODE_ERR.

> I know. I learned from someone here that assignment at initialization of
> a variable is always a good idea. I see it solves problems for me (in
> case of int types)

I disagree, but that's a controversial opinion, and I won't bother
arguing it again. However, since you've already initialized it to
CODE_ERR, there's no need to set it to that value a second time.

...

>>>      if(NULL == q->head)
>>>    {
>>>      printf("Removing Last element left\n"); q->head = q->tail =
>> NULL;

>> You already know q->head is NULL.

> yeah. So, instead of s->head = s->tail = NULL, I could have used s->tail
> = s->head. It was just a matter of style for me.

or s->tail = NULL, which is even simpler.
--
James Kuyper

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
arnuld  
View profile  
 More options May 9 2012, 9:18 am
Newsgroups: comp.lang.c
From: arnuld <sunr...@invalid.address>
Date: 09 May 2012 13:18:08 GMT
Local: Wed, May 9 2012 9:18 am
Subject: Re: Remving an element from Queue

> On Tue, 08 May 2012 23:21:06 -0700, Barry Schwarz wrote:
>> On 09 May 2012 05:43:02 GMT, arnuld <sunr...@invalid.address> wrote:
>>  p = malloc(1 * sizeof *p);
> What is the point of multiplying by 1?

Because it makes me remember that malloc() takes number of elements. It
sounds strange but I do forget to add number of elements most of the
times.

> Assume the queue consists of nodes containing 2, 1, 3, 1 and num is 1.

>>  for(current = q->head; current; current = current->next)
> Whenever you free current in the loop, the third expression above
> invokes undefined behavior on the next iteration.

It did not. Now I know why. After free(current), current may be pointing
to garbage. That's why the practice of setting the pointer to NULL after
free() was created.

Oddly, code worked fine all the time on my machine producing correct
results for 8 hours. Just now it Segfaulted.

> q->tail now points to node containing 2 which is same as q->head. Your q
> is now broken.

It is broke, Still trying to figure out how to write it correctly.

> I think the if test should be on the pointers, not on num:
>      if (current = q->tail)

aah... pointers do compare equal like int
(you meant current == q->tail)

> Since you have managed to create the situation, you might also want to
> add the following to the end of the if:
>       || q->tail->next != NULL

I understood my mistake. Like I said, I did the analysis after reading
your analysis I can see that head/tail pointing at wrong places, so I
should make a check for that too ?  No, unlike earlier now I think those
checks will not save these programming errors I am making. I better set
pointers right rather than spending my typing-energy to avoid/find errors.

> This demonstrates you don't use q->tail so why bother maintaining it?

q->tail to add, q->head to remove. Thats the purpose.

--
 arnuld
http://LispMachine.Wordpress.com


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Barry Schwarz  
View profile  
 More options May 9 2012, 1:59 pm
Newsgroups: comp.lang.c
From: Barry Schwarz <schwa...@dqel.com>
Date: Wed, 09 May 2012 10:59:17 -0700
Local: Wed, May 9 2012 1:59 pm
Subject: Re: Remving an element from Queue
On 09 May 2012 13:18:08 GMT, arnuld <sunr...@invalid.address> wrote:

>> On Tue, 08 May 2012 23:21:06 -0700, Barry Schwarz wrote:

>>> On 09 May 2012 05:43:02 GMT, arnuld <sunr...@invalid.address> wrote:

>>>  p = malloc(1 * sizeof *p);

>> What is the point of multiplying by 1?

>Because it makes me remember that malloc() takes number of elements. It
>sounds strange but I do forget to add number of elements most of the
>times.

Better to remember something true.  malloc takes number of bytes.
calloc takes number of elements and number of bytes per element but
involves extra overhead which is not needed here.

>> Assume the queue consists of nodes containing 2, 1, 3, 1 and num is 1.

>>>  for(current = q->head; current; current = current->next)

>> Whenever you free current in the loop, the third expression above
>> invokes undefined behavior on the next iteration.

>It did not. Now I know why. After free(current), current may be pointing
>to garbage. That's why the practice of setting the pointer to NULL after
>free() was created.

After free(current), current is indeterminate and doesn't point
anywhere.  Whether or not you set current to NULL after the free, any
attempt to dereference current, as in the expression current->next,
invokes undefined behavior.

>Oddly, code worked fine all the time on my machine producing correct
>results for 8 hours. Just now it Segfaulted.

Consider yourself lucky.  Frequently undefined behavior waits until an
important customer is present for the demo.

>> q->tail now points to node containing 2 which is same as q->head. Your q
>> is now broken.

>It is broke, Still trying to figure out how to write it correctly.

>> I think the if test should be on the pointers, not on num:
>>      if (current = q->tail)

>aah... pointers do compare equal like int
>(you meant current == q->tail)

Yes, I make this mistake more often than I care to admit.

>> Since you have managed to create the situation, you might also want to
>> add the following to the end of the if:
>>       || q->tail->next != NULL

>I understood my mistake. Like I said, I did the analysis after reading
>your analysis I can see that head/tail pointing at wrong places, so I
>should make a check for that too ?  No, unlike earlier now I think those
>checks will not save these programming errors I am making. I better set
>pointers right rather than spending my typing-energy to avoid/find errors.

>> This demonstrates you don't use q->tail so why bother maintaining it?

>q->tail to add, q->head to remove. Thats the purpose.

True.  I apologize for my excess sarcasm.

--
Remove del for email


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
arnuld  
View profile  
 More options May 10 2012, 8:26 am
Newsgroups: comp.lang.c
From: arnuld <arnuld.miz...@gmail.com>
Date: Thu, 10 May 2012 05:26:52 -0700 (PDT)
Local: Thurs, May 10 2012 8:26 am
Subject: Re: Remving an element from Queue

> On May 9, 10:59 pm, Barry Schwarz <schwa...@dqel.com> wrote:
>> On 09 May 2012 13:18:08 GMT, arnuld <sunr...@invalid.address> wrote:
>>Because it makes me remember that malloc() takes number of elements. It
>>sounds strange but I do forget to add number of elements most of the
>>times.
> Better to remember something true.  malloc takes number of bytes.
> calloc takes number of elements and number of bytes per element but
> involves extra overhead which is not needed here.

calloc() = malloc() + memset() ??

> After free(current), current is indeterminate and doesn't point
> anywhere.  Whether or not you set current to NULL after the free, any
> attempt to dereference current, as in the expression current->next,
> invokes undefined behavior.

understood very well.

> >> Since you have managed to create the situation, you might also want to
> >> add the following to the end of the if:
> >>       || q->tail->next != NULL

> True.  I apologize for my excess sarcasm.

ah.. cmon Barry. I liked your sarcasm, especially this one:

"Since you have managed to create the situation, you might also want
to add the following to the end of the if:       || q->tail->next !=
NULL "

Becaus of that I realized my checks were stupid. Checks are good but
not the ones I am doing , they are programming errors. Still can't
figure out how to remove an element from queue :\


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
nick_keighley_nos...@hotmail.com  
View profile  
 More options May 11 2012, 3:11 am
Newsgroups: comp.lang.c
From: nick_keighley_nos...@hotmail.com
Date: Fri, 11 May 2012 00:11:37 -0700 (PDT)
Local: Fri, May 11 2012 3:11 am
Subject: Re: Remving an element from Queue

On Thursday, May 10, 2012 1:26:52 PM UTC+1, arnuld wrote:
> > On May 9, 10:59 pm, Barry Schwarz <schwa...@dqel.com> wrote:
> >> On 09 May 2012 13:18:08 GMT, arnuld <sunr...@invalid.address> wrote:
> >>Because it makes me remember that malloc() takes number of elements.

no. The parameter is the number of bytes (chars)

> >> It
> >>sounds strange but I do forget to add number of elements most of the
> >>times.

> > Better to remember something true.  malloc takes number of bytes.
> > calloc takes number of elements and number of bytes per element but
> > involves extra overhead which is not needed here.

> calloc() = malloc() + memset() ??

depends what your "+" ooperator does! Note calloc() allocates an array of elements. But I'm sure most implementations of calloc() call malloc() (or both call some internal allocator)

<snip>


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
88888 Dihedral  
View profile  
 More options May 11 2012, 3:39 am
Newsgroups: comp.lang.c
From: 88888 Dihedral <dihedral88...@googlemail.com>
Date: Fri, 11 May 2012 00:39:15 -0700 (PDT)
Local: Fri, May 11 2012 3:39 am
Subject: Re: Remving an element from Queue
arnuld於 2012年5月8日星期二UTC+8下午4時09分39秒寫道:

I checked your code that I assume it requires not only the standard
operations of a queue.

I suggest you should use a link list.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Barry Schwarz  
View profile  
 More options May 14 2012, 6:53 pm
Newsgroups: comp.lang.c
From: Barry Schwarz <schwa...@dqel.com>
Date: Mon, 14 May 2012 15:53:04 -0700
Local: Mon, May 14 2012 6:53 pm
Subject: Re: Remving an element from Queue
On Thu, 10 May 2012 05:26:52 -0700 (PDT), arnuld

<arnuld.miz...@gmail.com> wrote:
>> Better to remember something true.  malloc takes number of bytes.
>> calloc takes number of elements and number of bytes per element but
>> involves extra overhead which is not needed here.

>calloc() = malloc() + memset() ??

As long as malloc doesn't fail,
    calloc(a,b) = memset(malloc(a*b),0,a*b)

--
Remove del for email


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
lawrence.jo...@siemens.com  
View profile  
 More options May 15 2012, 5:42 pm
Newsgroups: comp.lang.c
From: lawrence.jo...@siemens.com
Date: Tue, 15 May 2012 17:42:46 -0400
Local: Tues, May 15 2012 5:42 pm
Subject: Re: Remving an element from Queue

Barry Schwarz <schwa...@dqel.com> wrote:

> As long as malloc doesn't fail,

And a*b doesn't overflow,

>     calloc(a,b) = memset(malloc(a*b),0,a*b)

--
Larry Jones

Something COULD happen today.  And if anything DOES,
by golly, I'm going to be ready for it! -- Calvin


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Barry Schwarz  
View profile  
 More options May 15 2012, 7:40 pm
Newsgroups: comp.lang.c
From: Barry Schwarz <schwa...@dqel.com>
Date: Tue, 15 May 2012 16:40:21 -0700
Local: Tues, May 15 2012 7:40 pm
Subject: Re: Remving an element from Queue

On Tue, 15 May 2012 17:42:46 -0400, lawrence.jo...@siemens.com wrote:
>Barry Schwarz <schwa...@dqel.com> wrote:

>> As long as malloc doesn't fail,

>And a*b doesn't overflow,

>>     calloc(a,b) = memset(malloc(a*b),0,a*b)

Unsigned arithmetic cannot overflow.

Given the wording in 7.20.3.1, where the allocated space constitutes a
single array, I have no idea what happens when the arithmetic product
a*b exceeds the value of SIZE_MAX.  Under such conditions I believe
calloc should fail and return NULL but the memset expression above is
under no such obligation.

--
Remove del for email


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
James Kuyper  
View profile  
 More options May 15 2012, 11:03 pm
Newsgroups: comp.lang.c
From: James Kuyper <jameskuy...@verizon.net>
Date: Tue, 15 May 2012 23:03:39 -0400
Local: Tues, May 15 2012 11:03 pm
Subject: Re: Remving an element from Queue
On 05/15/2012 07:40 PM, Barry Schwarz wrote:

> On Tue, 15 May 2012 17:42:46 -0400, lawrence.jo...@siemens.com wrote:

>> Barry Schwarz <schwa...@dqel.com> wrote:

>>> As long as malloc doesn't fail,

>> And a*b doesn't overflow,

>>>     calloc(a,b) = memset(malloc(a*b),0,a*b)

> Unsigned arithmetic cannot overflow.

> Given the wording in 7.20.3.1, where the allocated space constitutes a
> single array, I have no idea what happens when the arithmetic product
> a*b exceeds the value of SIZE_MAX. ...

calloc(a,b) must either return a pointer to enough memory to store 'a'
objects, each of size 'b' bytes, or a null pointer. If the mathematical
product of a*b is greater than SIZE_MAX, then (size_t)(a*b) bytes will
not be sufficient to meet that requirement - but the requirement still
holds. Therefore, calloc(a,b) must either return a null pointer, or
allocate sufficient memory by some mechanism other than malloc(a*b).
--
James Kuyper

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Messages 1 - 25 of 39   Newer >
« Back to Discussions « Newer topic     Older topic »