Thread: Malloc and Automatic variable deallocation

  1. #1
    Registered User
    Join Date
    Dec 2004
    Posts
    9

    Malloc and Automatic variable deallocation

    Hello World,


    The scenario

    I have function called int ReturnObject(char *source,char* dest);

    The objective of this function is to return a dest object by passing source object.

    Example:
    Code:
    int ReturnObject(char* source,char* dest){
    
    int string_length = (strlen(source))+1;
    char* real_result = "";
    char* buffer =(char *)malloc(string_length);
    
    buffer = strcpy(buffer, dest);
    
    //--------- I AM NOT ABLE TO THIS ---- HENCE SEGMENTATION ERROR---//
    real_result = strcpy(buffer,"World");
    
    free(buffer);
    
    //--- I THINK?!
    dest = &real_result;
    }
    
    ///------------ Intention ---------------------//
    int main(int argc,char *argv[]){
    char* source ="Hello";
    
    char* dest="";
    
    if(ReturnObject(source,&dest)==EXIT_SUCCESS)
                 if(dest == "World")
                       printf("Hello New World");
    
    }

    However Almost works:
    Code:
    int string_length = (strlen(source))+1;
    char byte = '\0';
    
    //--------- ALMOST worked---//
    strcpy(&byte,"World");
    
    
    //--- I THINK?!
    dest = &byte;
    source=""; //----------- This line for some reason chops the ' dest ' to Original Strlen to 4 bytes?
    
    dest =0;


    Why does this happen?

    I hope I make sense.



    Thankyou WORLD.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You'll need a pointer to a pointer, if I understand what you're actually trying to do.
    Code:
    void fill( char **s, char *with )
    {
        if( with == NULL )
            *s = NULL;
        else
        {
            size_t x = strlen( with ) + 1;
    
            *s = malloc( x );
            strncpy( *s, with, x );
        }
    }
    If you want a pointer whose scope is outside of a function, to be updated to point to something new inside of a function, and to keep that change when the function returns, you need a pointer to that pointer. Just like if you want an integer outside a function to store some change you make in the function, you need a pointer to it.

    All objects are this way. To update an object inside a function, (to change its value, so it persists after the function ends) you need a pointer to that object. The only exception to this are arrays, which are degnerate. That is to say, boozers and tramps.

    Anyway, you'd use it something like so...
    Code:
    int main( void )
    {
        char *foo = NULL;
        char *bar = "baz";
    
        fill( &foo, bar );
    
        if( foo )
        {
            printf( "%s\n", foo );
            free( foo );
        }
    
        return 0;
    }
    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Aug 2006
    Posts
    100
    I'm confused... what are you actually trying to do?

    In any event, see comments...

    Code:
    int ReturnObject(char* source,char* dest){
    
    int string_length = (strlen(source))+1;          // What if source length  is less than 6? 
                                                                          // Your malloc() will
                                                                          // be too small to hold "World" below.
    char* real_result = "";                                  // You don't need = "" here, you just need to
                                                                         // delcare space to hold a char *
    char* buffer =(char *)malloc(string_length);// See above, and no check for NULL?
    
    buffer = strcpy(buffer, dest);                        // You don't need to use buffer as an lvalue here,
                                                                         // the assignment (probably optimized out) is
                                                                        // just assigning the address of buffer to itself.
    
    //--------- I AM NOT ABLE TO THIS ---- HENCE SEGMENTATION ERROR---//
    real_result = strcpy(buffer,"World");          // You are assigning a delcared local, which is
                                                                       // pointing to "" to a new address, this is probably
                                                                      // not what you intend.  Also, you don't know that
                                                                      // buffer is big enough to hold "World", also this
                                                                      // completely invalidates the above strcpy()
    
    free(buffer);                                              // freeing buffer will be a problem, as you are going
                                                                     // to try to return it's address as a valid memory block
                                                                    
    
    //--- I THINK?!
    dest = &real_result;                                //  Okay, except the memory block of real_result
                                                                   //  has been freed, and is invalid.  Also, dest was
                                                                   // passed in, do you want to overwrite it?
    }                                                             // You didn't return anything.

  4. #4
    Registered User
    Join Date
    Dec 2004
    Posts
    9

    Exclamation Continued...

    Current Code:
    Code:
    /*
    Will BE MULTITHREADED
    open a original file (source file)
    Look for the existing custom folder in the HOME directory
    If the HOME directory does not exist
    Then see if the specs exists in the /usr/local/share (Default)
    If the /usr/local/share does not exist then create a template
    create a temp
    */  
    
    #include <cliargs.h>
    
    short get_Stream(FILE* pSource,char* result);
    char* get_Copy(char* pStr);
    
    char* get_Copy(char* pStr){
    u_int8_t *temp =0;
    u_int8_t *final =0;
    u_int8_t byte = 0;
    u_int8_t dummy = 0;
    temp = pStr;
    int pos = 0;
    final = &dummy;
    //initilize the contents with new address
    do{
    	*final = &dummy;final++;
    	byte = *temp; temp++;
    }while(byte!='\0');
    
     temp = "";
     temp = pStr;
    //clean up everything
    
    char *results = "";
     results = strcpy( final,temp);
    
     return results;
    }//EOF
    
    short get_Stream(FILE* pSource,char* result){
      size_t buflen = 0; 
      char offset= 0; 
      int ret=EXIT_SUCCESS;
      fpos_t* pCurPos=0 ; //current file position
      fpos_t* pOldPos=0 ; //old file position
      char *finally = "";
      //get the starting File pointer position
      fgetpos(pSource,&pOldPos); 
      //find the newline  = 0x13
      //0F ==  15
      //0E == 14
      //0D == 13
      //0C == 12
      //0B == 11
      //0A == 10
      do{offset=0;  offset=fgetc(pSource); }
      while(offset!=0x0A && offset!=0x0D && offset!=EOF && offset!=NULL);
      //Are we at end of the file?
      if(offset == EOF || offset==NULL)
        ret= EXIT_FAILURE;
      else{
        //get the Current File position
        fgetpos (pSource,&pCurPos); 
        //Total Buffer Length
        buflen = (size_t)pCurPos - (size_t)pOldPos;    
        if(buflen == EXIT_FAILURE){
        //NEWLINE
          ret = EXIT_FAILURE;
        }else{
          //Reset Everything
          fsetpos (pSource,&pOldPos);    
          char *buffer = 0;
          //allocate memory for the new address register
          buffer = (char *)malloc(buflen);
          //read file buffer using fgets
          fgets(buffer,buflen,pSource);
          //copy the string to a automatic variable register
    	printf("%s",buffer);
          //finally = get_Copy(buffer);
          //free the contents
          free(buffer);  buffer=0;
          printf("Finally =%s",finally);
        }//ELSE
      }//ELSE
      pCurPos = 0;
      pOldPos = 0;   
      return ret;
    }//EOF
      
    int main(int argc,const char* argv[]){
    
      struct FileSettings{
        //  DIR *pFolder;
        FILE rTmpFile;
        FILE rSourceFile;
        const char* ATOMIC_NAME;
      };
    
      struct FileSettings setting;
       //setting.ATOMIC_NAME = "/home/generic/config.log";
       setting.ATOMIC_NAME = "/home/SatishAt/config.log";
      //    setting.ATOMIC_NAME = "/usr/share/units.dat";
      FILE *pFile = 0;
    
      printf("%s\n",setting.ATOMIC_NAME); 
      pFile = fopen(setting.ATOMIC_NAME,"rb");
    
      if(pFile==NULL){
          printf("File not found");
          exit(EXIT_FAILURE);
        }
      else{
        fseek(pFile,SEEK_SET,SEEK_SET);
      }
      char* ret = "";
    while(feof(pFile)==EXIT_SUCCESS){
      if(get_Stream(pFile,ret)==EXIT_SUCCESS){
          printf("<2>\n<1>");
      }
     }
     fclose(pFile);
    }//End of Main Application

    pseudocode:
    Read the File
    Get the length of each line
    allocate memory for each line
    return the contents of allocated memory with a different memory address
    free the existing allocated memory
    print the previous allocated contents on the screen.

    About:
    get_Copy() : Returns a copy of string pointer which was allocated by malloc into a string pointer which returns from a different memory address.


    I have got Linux and cygwin to expirement to test these code.
    In Linux the get_Copy function returns a Segmentation error after while but it does not the entire line of the File Pointer.


    In cygwin it does not display anything on the screen.

    I hope I have cleared the confusion.

    Ultimately how do I get rid of the segmentation error created by get_Copy and make it have all the contents of a allocated string but returing it to different pointer object.


    Thanks for the HELP.
    http://cboard.cprogramming.com/images/icons/icon4.gif
    Exclamation

  5. #5
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    A stupid question: Why are you attempting to read the length of the line, allocate memory for it, _THEN_ read the line?? If you are wanting to read the file and put it into a dynamic array of chars why no do something like:
    Code:
    char **readfile(const char *filename){
        FILE *file;
        char *tmp, **list = NULL;
        int listlen = 0;
    
        if ((file = fopen(filename, "rb")) == NULL){
            return NULL;
        }
        tmp = malloc(1024);
        while (!feof(file)){
            if (fscanf(file, "%[^\n]\n", tmp)){
                listlen++;
                list = (char **) realloc(list, sizeof(char *) * listlen);
                list[listlen - 1] = strdup(tmp);
            }
        }
        // Now, create a blank location to store a NULL in the last element (so you don't have to store the length
        list = (char **) realloc(list, sizeof(char *) * (listlen + 1));
        list[listlen] = NULL;
        fclose(file);
        free(tmp);
        return list;
    }
    I do this in many of my programs. I even have a freebuff that parses the list and removes all the memory. I have found that this is the best way (for me) to manipulate text files (such as /etc files etc .

    Andy
    Last edited by Kennedy; 08-14-2006 at 10:56 PM.

  6. #6
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by Kennedy
    Code:
        while (!feof(file)){
            if (fscanf(file, "%[^\n]\n", tmp)){
                listlen++;
                list = (char **) realloc(list, sizeof(char *) * listlen);
    Ick. FAQ, etc.
    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.*

  7. #7
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Code:
        char *tmp
    ...
        tmp = malloc(1024);
    What's the point?
    Code:
    char tmp[1024];
    If you understand what you're doing, you're not learning anything.

  8. #8
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    Quote Originally Posted by itsme86
    Code:
        char *tmp
    ...
        tmp = malloc(1024);
    What's the point?
    Code:
    char tmp[1024];
    Sorry, I'm old school. . . from the days of 64K memory. I'm still in the habbit of dynamic allocation of memory so as not to waist space.

    There was a time like that, you know.

  9. #9
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    I don't believe dynamic memory allocation ever wasted less space than growing the stack by 1KB, actually. 1KB of stack space uses exactly that much memory, whereas dynamic memory allocation has some internal memory overhead.
    If you understand what you're doing, you're not learning anything.

  10. #10
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Yeah but there was a time when the stack was only a few kb.
    Kurt

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Yeah, it still happens.

    We see the occasional post with int matrix[1000][1000] or suchlike, and the questions as to why it segfaults.

    For normal work, the char array on the stack ought to be good enough for most purposes.

    Of course, there's always going to be exceptions to the rule
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  12. #12
    Registered User
    Join Date
    Dec 2004
    Posts
    9

    Made new milestones....

    Hello WORLD

    Latest Code:
    Code:
    /*
    Will BE MULTITHREADED
    open a original file (source file)
    Look for the existing custom folder in the HOME directory
    If the HOME directory does not exist
    Then see if the specs exists in the /usr/local/share (Default)
    If the /usr/local/share does not exist then create a template
    create a temp
    */  
    
    #include <cliargs.h>
    
    short get_Stream(FILE* pSource,char* result);
    
    char* get_Copy(char* pStr);
    
    char* get_Copy(char* pStr){
      char *final=0;
      unsigned char byte = 0;
      unsigned char dummy = 0;
      final = &dummy;
    *final = &dummy;
    unsigned char *temp=0;temp = pStr;
      //initilize the contents with new address
    do{    byte = 0;byte = *temp;
    	*final = &byte;
    	final++; temp++;
    }while(byte!='\0');
    final++;
    *final='\0';
    temp = 0;temp = pStr;
      final = strcpy(final,temp);
      return final;
    }//EOF
    
    short get_Stream(FILE* pSource,char* result){
      size_t buflen = 0; 
      char offset= 0; 
      int ret=EXIT_SUCCESS;
      fpos_t* pCurPos=0 ; //current file position
      fpos_t* pOldPos=0 ; //old file position
      char *finally = 0;
      const char *buffer = 0;
      //get the starting File pointer position
      fgetpos(pSource,&pOldPos); 
      //find the newline  = 0x13
      //0F ==  15
      //0E == 14
      //0D == 13
      //0C == 12
      //0B == 11
      //0A == 10
      do{offset=0;  offset=fgetc(pSource); }
      while(offset!=0x0A && offset!=0x0D && offset!=EOF && offset!=NULL);
      //Are we at end of the file?
      if(offset == EOF || offset==NULL)
        ret= EXIT_FAILURE;
      else{
        //get the Current File position
        fgetpos (pSource,&pCurPos); 
        //Total Buffer Length
        buflen = (size_t)pCurPos - (size_t)pOldPos;    
        if(buflen == EXIT_FAILURE){
          ret = EXIT_FAILURE;
        }else{
          //Reset Everything
          fsetpos (pSource,&pOldPos);    
          //allocate memory for the new address register
          buffer = (const char *)malloc(buflen);
          //read file buffer using fgets
          fgets(buffer,buflen,pSource);
           
          //copy the string to a automatic variable register
         finally = get_Copy(buffer);
          //free the contents
          free(buffer); 
        }//ELSE
      }//ELSE
    //  buffer=0;
    printf("%s",finally);
      pCurPos = 0;
      pOldPos = 0;   
      return ret;
    }//EOF
      
    int main(int argc,const char* argv[]){
    
      struct FileSettings{
        //  DIR *pFolder;
        FILE* rTmpFile;
        FILE* rSourceFile;
        const char* ATOMIC_NAME;
      };
    
      struct FileSettings *pSetting=0;
        char* ret="";
      pSetting = (struct FileSettings *)malloc(sizeof(struct FileSettings));
    
      pSetting->ATOMIC_NAME = "/home/generic/config.log";
       
      pSetting->rSourceFile = fopen(pSetting->ATOMIC_NAME,"rb");
    
      if(pSetting->rSourceFile==NULL){
          printf("File not found");
        }
      else{
         fseek(pSetting->rSourceFile,SEEK_SET,SEEK_SET);
          while(feof(pSetting->rSourceFile)==EXIT_SUCCESS)
          if(get_Stream(pSetting->rSourceFile,ret)==EXIT_SUCCESS){
          printf("<2>\n<1>");
          }
      }
      fclose(pSetting->rSourceFile);
      free(pSetting);
    }//End of Main Application

    Question 1
    In stdout stream I get the following output:
    ( I specifed this) <1> (null) (null) The main output ( I specifed this) <2>
    How do I get rid of the null object from the output.


    I have nearly got the program to work.
    How do I clean up this program?

    Thanks for the help guys and girls( if any).

  13. #13
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
    char* get_Copy(char* pStr){
      char *final=0;
      unsigned char byte = 0;
      unsigned char dummy = 0;
      final = &dummy;
    *final = &dummy;
    What exactly are you trying to do with these last two lines of code? First off, a 'char *' is not the same as a 'unsigned char *'. Second, a 'char' is not an 'unsigned char *'.

    Now the next line...
    Code:
    unsigned char *temp=0;temp = pStr;
    Same thing here. Stop mixing your pointer types. Do you even compile with warnings on?

    Same song, second verse. Couldn't get better, so it's gotta get worse...
    Code:
    do{    byte = 0;byte = *temp;
    	*final = &byte;
    	final++; temp++;
    }while(byte!='\0');
    'final', which points to ... in theory ... one unsigned character, gets incremented. Now what is it pointing to?
    Code:
    final++;
    *final='\0';
    temp = 0;temp = pStr;
      final = strcpy(final,temp);
      return final;
    }//EOF
    So much bad code. *head asplodes*


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

  14. #14
    Registered User
    Join Date
    Dec 2004
    Posts
    9
    How would you create a function which a string object which the contents of malloc object?
    To answer this question i used function called get_Copy().


    To quzah:
    How would you rewrite this function?

  15. #15
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    How would you create a function which a string object which the contents of malloc object?
    Huh?
    If you understand what you're doing, you're not learning anything.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. When and when not to use malloc()?
    By John.H in forum C Programming
    Replies: 5
    Last Post: 03-24-2003, 06:00 PM