3

How would I free the memory allocated by strdup? I've tried using free(linepos) at the end of this function, but that causes my program to fail. I don't have linepos outside of this function, so I'm unable to free it anywhere else. Thank you in advance.

void putinqueue (queue *the_queue, FILE *input, char *filename) {
   char buffer[1024];
   for (int linenr = 1; ; ++linenr) {
      char *linepos = fgets (buffer, sizeof buffer, input);
      if (linepos == NULL) break;
      linepos = strchr (buffer, '\n');
      if (linepos == NULL) {
         fflush (NULL);
         fprintf (stderr, "%s: %s[%d]: unterminated line\n",
                  execname, filename, linenr);
         fflush (NULL);
         exit_status = EXIT_FAILURE;
      }else {
         *linepos = '\0';
      }
      linepos = strdup (buffer);
      assert (linepos != NULL);
      insert_queue (the_queue, linepos);
   }
}

EDIT: Here are the other functions. Sorry, copy and pasted the old source. This is the new one.

void insert_queue (queue *this, queue_item_t item) {
   //Inserts a new item at the end of queue.
   queue_node *temp = malloc(sizeof (struct queue_node));
   temp->item = item;
   temp->link = NULL;

   if (isempty_queue(this)) this->front = temp; 
   else this->rear->link = temp;
   this->rear = temp;
}

queue_item_t remove_queue (queue *this) {
   //This removes the first item from queue.
   assert (! isempty_queue (this));
   //Creates temp, and rVal and initializes them.
   queue_node *temp = this->front;
   queue_item_t rVal = temp->item;

   //Moves on to the next one.
   this->front = this->front->link;
   if (this->front == NULL) this->rear = NULL;
   //Free the unlinked node.
   free(temp);
   temp = NULL;
   return rVal;
}
Mickey
  • 117
  • 1
  • 10
  • 1
    "The returned pointer can be passed to free()" http://pubs.opengroup.org/onlinepubs/009696799/functions/strdup.html. Your issue is more likely about what `insert_queue` is doing. If it isn't making its own copy, then you're freeing memory which is still being used by the queue (and should more rightly become the queue's responsibility to free). – Dave Nov 17 '13 at 23:50
  • 1
    You're putting the pointer into your queue; you should `free` the memory when you delete the queue explicitly. If you aren't, you will have to start. – Joe Nov 17 '13 at 23:51
  • Is queue_item a typedef of a char * if not wtf are you doing? – Scotty Bauer Nov 17 '13 at 23:58
  • this line: `temp->item = item;` means that your queue is indeed using the same memory location. Don't free the pointer in your function, but instead free it only when you're finished with it; whatever calls `remove_queue` (i.e. pops the item from the queue) is responsible for freeing the memory once it has finished with it. – Dave Nov 18 '13 at 00:10
  • queue_item_t is a typedef of char*, correct. – Mickey Nov 18 '13 at 00:10
  • @Dave, at the end of my program, I use a while loop to print the queue. So how can I print and free at the same time? Also, how could I prevent it from using a different memory location? – Mickey Nov 18 '13 at 00:12
  • In remove queue you return the rValue, so you should be able to free that value after you print it or w/e you do with it. – Scotty Bauer Nov 18 '13 at 00:13
  • @Dave, wouldn't printing it remove a node, then print it? if I free it, it would remove another node (and not print it). – Mickey Nov 18 '13 at 00:15
  • For example : while (! isempty_queue (the_queue)) { printf ("%s\n", remove_queue (the_queue)); } – Mickey Nov 18 '13 at 00:16
  • When you remove the node, store it in a local variable. Then you can print and free that local variable. This is a very (very very) common pattern. – Dave Nov 18 '13 at 00:16
  • @Raymond do this `while (! isempty_queue (the_queue)) { queue_item_t * temp = remove_queue(the_queue) printf ("%s\n", temp); free(temp)` – Scotty Bauer Nov 18 '13 at 00:17
  • @Scotty I did: char * string = remove_queue (the_queue); Is there a difference between using char * and queue_item_t *? – Mickey Nov 18 '13 at 00:21
  • @Raymond it sounds like you have a line `typedef char* queue_item_t;` in your code, so you could use either `char*` or `queue_item_t` (no `*`) – Dave Nov 18 '13 at 00:25

0 Answers0