Organizational Research By

Surprising Reserch Topic

can we use free after returning a value in functions


can we use free after returning a value in functions  using -'c,function,pointers,memory-leaks,dynamic-memory-allocation'

In a function that returns char,  memory has to be allocated dynamically. But can we free the memory using free () after returning a value back to the calling function?

//Program to print today's and last 3 days weather data in a structure

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

struct weather
{
     char *date;
     int month;
     int day;
     int year;
     unsigned int h_temp;
     unsigned int l_temp;
     int max_wind_speed;
     int preciption;
     char notes [80];
};

char *chrdate(struct weather *wdt, int loop)
{
    char *stdate = (char*)calloc(11,sizeof(char));
    sprintf(stdate, "%d/%d/%d", (wdt+loop)->day,(wdt+loop)->month,(wdt+loop)->year);
    return stdate;
    free(stdate);
}

void prev_date(int loop, struct weather *pdate)
{
    int lmonth =  (pdate+(loop-1))->month-1; //assigning previous day's month to local variable

    if ( ((pdate+(loop-1))->day == 1) && ((pdate+(loop-1))->month == 1) )
    {
        (pdate+loop)->year = (pdate+(loop-1))->year-1 ;

        (pdate+loop)->month = 12;

        (pdate+loop)->day = 31;
    }
    else if (((pdate+(loop-1))->day == 1) && ((pdate+(loop-1))->month != 1))
    {
        (pdate+loop)->year = (pdate+(loop-1))->year ;
        (pdate+loop)->month = (pdate+(loop-1))->month-1 ;

        //assigned month as per struct tm
        if ( (lmonth == 4) || (lmonth == 6) || (lmonth == 9) || (lmonth == 11) )
        {
            (pdate+(loop))->day = 30; //assigning 30 days for respective months
        }
        //checking for leap year and assigning days for february
        else if (lmonth == 2)
        {
            if ((pdate+(loop-1))->year % 4 == 0)
            {
                (pdate+(loop))->day = 29;
            }
            else
            {
                (pdate+(loop))->day = 28;
            }
        }
        //assigning days for rest of the months
        else
        {
        (pdate+(loop))->day = 31;
        }
    }
    else if (   (pdate+(loop-1))->day != 1)
    {
        (pdate+loop)->year = (pdate+(loop-1))->year ;
        (pdate+loop)->month = (pdate+(loop-1))->month;
        (pdate+loop)->day = (pdate+(loop-1))->day-1;
    }
}

void collect_data (struct weather *pinfo)
{
     int loop;
     char yes_no[2];

     time_t curtime; //declaring time variable

     //storing current system time in the time variable
     time(&curtime);

     //storing current time to time structure
     struct tm * wdate = localtime (&curtime);


     for (loop=0;loop<4;loop++)
     {
            if (loop == 0)
            {
                (pinfo+loop)->day = wdate->tm_mday;
                (pinfo+loop)->month = wdate->tm_mon+1;
                (pinfo+loop)->year = wdate->tm_year+1900;               ;
            }
            else
            {
            prev_date(loop,pinfo);
            }

            (pinfo+loop)->date = chrdate(pinfo, loop);

            if (loop == 0)
            {
                printf("Today's weather details\n");
                printf("-----------------------\n");
            }
            else
            {
                printf("\n\nEnter weather data for %s\n",(pinfo+loop)->date);
                printf("------------------------------------");
            }

          printf("\nEnter the high temperature of the day:");
          scanf("\n%d",&(pinfo+loop)->h_temp);
          printf("\nEnter the low temperature of the day:");
          scanf("\n%d",&(pinfo+loop)->l_temp);
          printf("\nEnter the maximum wind speed of the day:");
          scanf("\n%d",&(pinfo+loop)->max_wind_speed);
          printf("\nEnter the perciption of the day:");
          scanf("\n%d",&(pinfo+loop)->preciption);
          printf("\nDo you have any notes about the weather of the day (y/n):");
          scanf("\n%[^\n]s",yes_no);

          if (strcmp(yes_no,"y")==0)
          {
                printf("\nNotes (Max Characters to be used is 80 incl. spaces):\n");
                scanf("\n%79[^\n]s",(pinfo+loop)->notes);
          }
          else
          {
            printf("Notes are blank. Processing save...");
          }
     }
}

int main ()
{
     struct weather info [4];
     int loop;
     collect_data(info);

     for (loop = 0; loop<4; loop++)
     {
     printf("%s\n",info[loop].date);
     }

     return 0;
}

    

asked Sep 9, 2015 by LukeReinhard
0 votes
5 views



Related Hot Questions

2 Answers

0 votes

You can't do this

char *chrdate(struct weather *wdt, int loop)
{
   char *stdate = (char*)calloc(11,sizeof(char));
   sprintf(stdate, "%d/%d/%d", (wdt+loop)->day,(wdt+loop)->month,(wdt+loop)->year);
   return stdate; // your function execution end here
   free(stdate); // the execution won't reach here
}

chrdate returns a pointer to memory you have allocated and assigned it to

(pinfo+loop)->date = chrdate(pinfo, loop);

You don't want to free() it since you will use it next.

for (loop = 0; loop<4; loop++)
{
  printf("%s\n",info[loop].date); // still use it here
}

Instead, you should call free((pinfo+loop)->date) when you have finished using that memory.

answered Sep 9, 2015 by JOTVeo
0 votes

This:

char *chrdate(struct weather *wdt, int loop)
{
    char *stdate = (char*)calloc(11,sizeof(char));
    sprintf(stdate, "%d/%d/%d", (wdt+loop)->day,(wdt+loop)->month,(wdt+loop)->year);
    return stdate;
    free(stdate); // unreachable code
}

the final line with free never gets executed because the function returns before that. Instead of that you must remove that line with free inside the function, and free it later, e.g.

char * ptr = chrdate(wdate, i);
// ... use ptr and free it when you are done with it.
free(ptr);
answered Sep 9, 2015 by EmoPaschke

...