[RESOLVED] Problem when passing reference to struct to function
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11

Thread: [RESOLVED] Problem when passing reference to struct to function

  1. #1
    Join Date
    Jun 2017
    Posts
    4

    [RESOLVED] Problem when passing reference to struct to function

    Hi there I have a problem regarding passing references as an argument to a function.
    That I would really like to have an expert opinion on.

    So I have this double** that I pass to function called func, which runs multiple times (several thousand times in some cases).

    This double (d) is part of a struct:

    Code:
                                                                                      
    typedef struct{                                                                                                                                           
      double **d;                                                                                                                                         
      char *k1;                                                                                                                                            
      char *l2;                                                                                                                                            
      std::vector<std::string> barcode;                                                                                                                            
      int n;                                                                                                                                             
      int p;                                                                                                                                               
      std::map <std::string,int> barcodeMap;                                                                                                                       
    }dgd;
    I then go and do boostrapping on d, meaning sampling rows from d randomly (with replacement), via this function:

    Code:
    void bootstrap(dgd org, dgd new, double** X_org2, double** X_org, double** X, int x) {
      for(int j=0;j<org.n;j++){
        int row = std::rand() % org.n;
        for(int k = 0; k < x; k++) {
          X[j][k] = X_org2[row][k];
          X_org[j][k] = X_org2[row][k];
          if(k<=2){
            org.d[j][k] = new.d[row][k];
          }
        }
      }
    }
    The problem is that sometimes when I run this program I get a segmentation fault after X bootstrapping runs.

    However I have discovered that this only happens when I call the function func with a reference to my struct:
    (In which it also runs faster, which I guess is consistent with theory)
    Code:
    int func(const dgd &new, double* n, int p, double** X,double* q,double** &X_new,double* &q_new, double** X_org)
    And not when I do like this:

    Code:
    int func(const dgd new, double* n, int p, double** X,double* q,double** &X_new,double* &q_new, double** X_org)
    The error I get is:

    Code:
    ==83081== Invalid write of size 8
    ==83081== at 0x403147: main
    ==83081== Address 0x48d012a8 is 16 bytes after a block of size 40 alloc'd
    ==83081== at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==83081== by 0x402CD0: main
    So does anyone have an idea of why this is happening? I mean one should be able to pass a struct as a reference in C++. Does it have anything to do with the implementation of the boostrap function?

  2. #2
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    5,449

    Re: Problem when passing reference to struct to function

    Can you post the code body for the function func() as you have only posted the code for bootstrap().
    All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/

    C, C++ Compiler: Microsoft VS2017.2

  3. #3
    Join Date
    Jun 2003
    Location
    Armenia, Yerevan
    Posts
    689

    Re: Problem when passing reference to struct to function

    The problem is most probably concerned with improper allocation of the memory for the pointers.
    It'll be interesting to see how the freeing of the memory is organized.
    Last edited by AvDav; June 5th, 2017 at 02:30 PM.
    Popular opinion is the greatest lie in the world.

  4. #4
    Join Date
    Jun 2017
    Posts
    4

    Re: Problem when passing reference to struct to function

    Here is the func:

    Code:
    int func(const dgd &new, double* n, int y, double** X,double* q,double** &X_new,double* &q_new, double** X_org, double* N){
    	calc(q, X, new.n, N, y,new.d, X_new, q_new, X_org);
    
    	double tol = 0.001;
    	if(calcThres(q,q_new,y)< tol){
    		return 0;
    	}
    
      return 1;
      
    	}
    And here is the calc inside it:



    Code:
    void calc(double* q, double** X, int n, double* N, int y,double **d,double **X_new,double *q_new, double** X_org) {
      double sumA[y];
      double sumB[y];
      
      
      double sumA2[y];
      double sumB2[y];
      for(int k=0;k<y;k++){ 
          sumA2[k]=0;
          sumB2[k]=0;
      }
      for(int j=0;j<n;j++){   
        for(int k=0;k<y;k++){ 
          sumA[k]=0;
          sumB[k]=0;
        }
        double p1=1;
        double p2=1;
        double h=0;
        for(int k=0;k<y;k++){ 
          
          p1 += X[j][k] * q[k];
          p2 += (1-X[j][k]) * q[k];
          
          double w0=(p2)*(p2)*d[j][2];
          double w1=2*(p2)*p1*  d[j][1];
          double w2=p1*p1*        d[j][0];
          double sum=w0+w1+w2;
          
          h=(w1+2*w2)*sum;
        }
        for(int k=0;k<y;k++){
          
          sumA[k] = h / (p1) * (q[k]*X[j][k]); 
          sumB[k] = h / p2 * (q[k]*(1-X[j][k]));
          sumA2[k] += sumA[k];
          sumB2[k] += sumB[k];
          sumA[k] += y[k]*2*X_org[j][k];
          sumB[k] += 2*y[k]-(2*y[k]+X_org[j][k]);      
        }
        for(int k=0;k<y;k++){
          
          X_new[j][k]=sumA[k]+sumB[k];
        }
        
      }
      for(int k=0;k<y;k++){ 
        q_new[k]=(sumA2[k]+sumB2[k])/(2.3*n);
      }
      
    }
    I allocate the struct like this:

    Code:
    dgd allocDgd(int n){
      dgd new;
      new.n = n;
      new.m1 = new char[n];
      new.m2 = new char[n];
    
      new.y = 2;
      new.d = allocDouble(n,6);
      
      for(int s=0;SIG_COND&& (s<n);s++){
        new.m1[s] = '0';
        new.m2[s] = '0';
      
      }
      return(new);
    }
    Where:

    Code:
    double **allocDouble(size_t x,size_t y){
      double **d = new double*[x];
      for(size_t i=0;i<x;i++){
        d[i] = new double[y];
      }
      return d;
    }
    And I deallocate it like this:

    Code:
    void dallocDgd(dgd &new){
      for(int i=0;i<new.n;i++){
        delete [] new.d[i];  
      }
        
      delete [] new.m1;
      delete [] new.m2;
      delete [] new.d;
    
    }

  5. #5
    Join Date
    Jun 2003
    Location
    Armenia, Yerevan
    Posts
    689

    Re: Problem when passing reference to struct to function

    Why not to use std::vector instead, then it would be possible to clean some mess code in your project.
    Popular opinion is the greatest lie in the world.

  6. #6
    Join Date
    Jun 2017
    Posts
    4

    Re: Problem when passing reference to struct to function

    I have tried that, and I found that using pointers is considerably faster, when doing many iterations.

  7. #7
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    5,449

    Re: Problem when passing reference to struct to function

    Code:
    double sumA[y];
      double sumB[y];
      
      
      double sumA2[y];
      double sumB2[y];
    What compiler are you using as that's not standard c++ as the array size is determined at run-time and not compile time.

    However, you are passing dgd (which contains dynamic memory pointers) by value (eg returning new from allocDgd() - though a variable called new isn't recommended) without having a proper copy-constructor for dgd - which is messing with memory. I would suggest that you implement a constructor, destructor, copy constructor, move constructor, copy assignment and move assignment for dgd. Also with c++ you don't need the typedef as you do with c.
    Last edited by 2kaud; June 5th, 2017 at 02:55 PM.
    All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/

    C, C++ Compiler: Microsoft VS2017.2

  8. #8
    Join Date
    Jun 2003
    Location
    Armenia, Yerevan
    Posts
    689

    Re: Problem when passing reference to struct to function

    Premature optimization is evil, (C) D. Knuth.
    Popular opinion is the greatest lie in the world.

  9. #9
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    5,449

    Re: Problem when passing reference to struct to function

    Quote Originally Posted by lolller View Post
    I have tried that, and I found that using pointers is considerably faster, when doing many iterations.
    Were you passing the vectors by value or by reference? If by value, then yes using vectors would be much slower then passing pointers.
    All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/

    C, C++ Compiler: Microsoft VS2017.2

  10. #10
    Join Date
    Feb 2017
    Posts
    99

    Re: Problem when passing reference to struct to function

    Quote Originally Posted by lolller View Post
    I have tried that, and I found that using pointers is considerably faster, when doing many iterations.
    I doubt that.

    If it's not legacy code this kind of error-prone programming is inexcusable today. It's unprofessional. You are deliberately shooting yourself in the foot and then come asking why it hurts.

    I suggest you rewrite in modern C++ concentrating on high quality working code. If it turns out slower than expected ask about that instead.

  11. #11
    Join Date
    Jun 2017
    Posts
    4

    Re: Problem when passing reference to struct to function

    Ok thanks a lot for the input I restructured it to make it work with vectors, passing them by reference.

    I used G++, which allows for array to be declared with variables and thereby for the size to be determined at run-time instead of compile-time.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This a Codeguru.com survey!


On-Demand Webinars (sponsored)