Advice needed - copy struct

This is a discussion on Advice needed - copy struct within the C Programming forums, part of the General Programming Boards category; Hi I have a problem. I am working on a code that has been poorly maintained . What i need ...

  1. #1
    Registered User
    Join Date
    Jan 2011
    Posts
    176

    Advice needed - copy struct

    Hi

    I have a problem. I am working on a code that has been poorly maintained . What i need is to use one function from the code to get some value which is then needed for some other computations. Example:


    Code:
    
    typdef struct ScoreKey{
    ...
    }ScoreKey;
    
    int main(){
    
      ScoreKey * sc;
    
      FillScKey(sc);
    
      value = UseBlackBoxFunc(sc);
    
      Compute(sc,value);
    
      return 0;
    }
    As you can see i need to pass a struct to UseBlackBoxFunc() function.
    The problem is that, the function UseBlackBoxFunc(sc) changes some of the variables(values) of sc struct, so sc before and after using UseBlackBoxFunc() function is not the same. However i need it to be for Compute() func.

    These functions are very complicated and hard to read. Moreover struct's that are send around are also complicated(example):

    Code:
    typedef struct BlScBlk {
       Boolean     alphabet; 
       Uint1    code; 
       Int2     size;  
       Int2     start;  
       char*    name;  
       LiNode*   comments;   
       SBlScMtx* matrix;   
       SPBlScMtx* Mmatrix;  
       Int4  losc;  
       Int4  hisc;  
      
       BlScFreq** ftp;  
       BlKBlk **gbt_std,
                        **gbt_p,
                        **gbt_gap_tmp, 
                        **gbt_gap_ps;  
       
       Int4 number_of_contexts; 
       Uint1*   ambiguous_res; 
       Int2     ambig_size, 
             ambig_occupy;  
       Boolean  round_down; 
    } ScoreKey;
    NO comments or anything and there are at leas 9-10 of those that need to be passed to a function. So instead loosing a year of trying to decipher everything, i was thinking maybe there is a better solution to my problem, like this one:


    Code:
    
    typdef struct ScoreKey{
    ...
    }ScoreKey;
    
    int main(){
    
      ScoreKey * sc;
    
      FillScKey(sc);
    
      sc_tmp = MakeCopy(sc);
    
      value = UseBlackBoxFunc(sc_tmp);
      
      Destruct(sc_tmp);
      Compute(sc,value);
    
      return 0;
    }
    Make a copy. Send a copy to BlackBox func. Destroy a copy. Is something like this possible on such complicated structures?? And if yes how?

    Is there a better solution ??

    Thank you

    baxy
    Last edited by baxy; 08-22-2013 at 09:55 AM.

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,564
    I can't think of a better solution of the top of my head.

    What you're talking about is a deep copy: you make a copy of the struct, and every sub-struct or allocated object recursively. This is possible if you know how every element and sub-element of a ScoreKey is created, and you can make a true copy of each one. Imagine you just malloc a ScoreKey, say temp_sc, and make a shallow copy:
    Code:
    ScoreKey *sc;
    ScoreKey sc_tmp;
    FillScKey(sc);
    sc_tmp = *sc;  // this will do a shallow copy of all elements
    value = UseBlackBoxFunc(&sc_tmp)
    However, all the pointers in sc_tmp point to the same objects as the corresponding pointers of sc. Thus, if UseBlackBoxFunc modifies the matrix element of sc_tmp, it will have modified the matrix element of sc as well.

    The solution, while tedious, is to provide a deep copy function for each data type that is dynamically allocated. Then your code would look like:
    Code:
    sc_tmp = DeepCopyScKey(sc);
    ...
    ScoreKey *DeepCopyScKey(ScoreKey *sc)
    {
        ScoreKey *new_sc = malloc(sizeof(*new_sc));
    
        new_sc->alphabet = sc->alphabet;  // simple assignment
        ...
        new_sc->name = strdup(sc->name);
        new_sc->comments = DeepCopyLiNode(sc->comments);  // DeepCopyLiNode would be similar to this function
        ...
        return new_sc;
    }
    Note, you'll have to have similar functions to recursively free each part of a ScoreKey, to avoid memory leaks. Don't forget to be a good boy/girl and check that each malloc call succeeded.

    If you don't have the strdup function (I think it's a POSIX function), consider defining it, possibly as part of one of your basic libraries. It's a simple malloc-strcpy, but is very handy. Google will have more info on funciton signature, etc, if you care to match the POSIX function. Also a memdup function may come in handy, just like strdup, but takes a size parameter and does a malloc + memcpy.

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    The strdup function is in Pelles C for Windows, by default. From the help section:

    _strdup function [not standard C]


    Purpose:
    Duplicates a string in allocated memory.



    Syntax:
    char * _strdup(const char * string);



    Declared in:
    <string.h>



    Description:
    The _strdup function uses malloc to allocate space for a copy of the string pointed to by string, and then copies the string to the allocated space including the terminating null character.



    Returns:
    A pointer to the allocated space, or a null pointer in case of error.


    See also:
    The _wcsdup function.



Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Advice needed
    By baxy in forum C Programming
    Replies: 4
    Last Post: 08-08-2013, 02:53 PM
  2. Advice needed
    By Incantrix in forum Game Programming
    Replies: 4
    Last Post: 10-18-2010, 08:39 PM
  3. Copy vector [need advice]
    By sugarfree in forum C++ Programming
    Replies: 12
    Last Post: 04-24-2010, 01:05 AM
  4. Job advice needed regarding C++
    By joeyzt in forum A Brief History of Cprogramming.com
    Replies: 2
    Last Post: 06-20-2003, 01:10 AM
  5. advice needed
    By unregisterd in forum C Programming
    Replies: 3
    Last Post: 10-19-2002, 07:04 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21