By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,953 Members | 1,109 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,953 IT Pros & Developers. It's quick & easy.

Scope of Dynamically Allocated Arrays in class member functions

emaghero
P: 85
I have the following class declaration
Expand|Select|Wrap|Line Numbers
  1. class class_name{
  2. public:
  3.    class_name(); // Constructor
  4.  
  5. // Member functions
  6.    void function_1();
  7.    void function_2(double *mat);
  8.    void function_3();
  9.  
  10.    void function_2_re_def(double *mat);
  11.    void function_3_re_def();
  12.  
  13. public:
  14.    int rows;
  15.    int cols;
  16.  
  17.    double *v1;
  18.    double *v2;
  19. };
  20.  
The member functions, function_1 and function_2, perform the same task. They store some computed data in the array. I define function_1 as follows
Expand|Select|Wrap|Line Numbers
  1. void class_name::function_1()
  2. {
  3.    v1=new(double[(rows+1)*(cols+1)]);
  4.  
  5.    double some_number;
  6.  
  7.    for(int i=1;i<=rows;i++){
  8.       for(int j=1;j<=cols;j++){
  9.          *(v1+i*(cols+1)+j)=some_number;
  10.       }
  11.    }
  12. }
  13.  
I define function_2 as
Expand|Select|Wrap|Line Numbers
  1. void class_name::function_2(double *mat)
  2. {
  3.    mat=new(double[(rows+1)*(cols+1)]);
  4.  
  5.    double some_number;
  6.  
  7.    for(int i=1;i<=rows;i++){
  8.       for(int j=1;j<=cols;j++){
  9.          *(mat+i*(cols+1)+j)=some_number;
  10.       }
  11.    }
  12. }
  13.  
The only difference is that I want to pass an array to the function that does the same task instead of being limited as I am in function_1 which will only allow the operation to be performed on a single array. I want to be able to call function_1 or function_2 inside another function to do something else with the computed data. If I use function_1 inside this other function, called function_3, no problems arise.
Expand|Select|Wrap|Line Numbers
  1. void class_name::function_3()
  2. {
  3.    // perform the computation, 
  4.    function_1();
  5.  
  6.    // The data in v1 can be accessed inside this function
  7.  
  8.    // Print the data to screen
  9.    for(int i=1;i<=rows;i++){
  10.       for(int j=1;j<=cols;j++)
  11.          cout<<*(v1+i*(cols+1)+j)<<" ";
  12.       cout<<endl;
  13.    }
  14. }
  15.  
However, I cannot get this to work if I use function_2, i.e. if I define function_3 as
Expand|Select|Wrap|Line Numbers
  1. void class_name::function_3()
  2. {
  3.    // perform the computation, 
  4.    function_2(v2);
  5.  
  6.    // The data in v2 cannot be accessed inside this function
  7.  
  8.    // Print the data to screen fails, program crashes
  9.    for(int i=1;i<=rows;i++){
  10.       for(int j=1;j<=cols;j++)
  11.          cout<<*(v2+i*(cols+1)+j)<<" ";
  12.       cout<<endl;
  13.    }
  14. }
  15.  
What is more infuriating is that if I redefine function 2 by removing the call to new
Expand|Select|Wrap|Line Numbers
  1. void class_name::function_2_re_def(double *mat)
  2. {
  3.    double some_number;
  4.  
  5.    for(int i=1;i<=rows;i++){
  6.       for(int j=1;j<=cols;j++){
  7.          *(mat+i*(cols+1)+j)=some_number;
  8.       }
  9.    }
  10. }
  11.  
and redefine function_3 as
Expand|Select|Wrap|Line Numbers
  1. void class_name::function_3_re_def()
  2. {
  3.    // perform the computation, 
  4.    v2=new(double[(rows+1)*(cols+1)]);
  5.    function_2(v2);
  6.  
  7.    // The data in v2 can now be accessed inside this function
  8.  
  9.    // Print the data to screen 
  10.    for(int i=1;i<=rows;i++){
  11.       for(int j=1;j<=cols;j++)
  12.          cout<<*(v2+i*(cols+1)+j)<<" ";
  13.       cout<<endl;
  14.    }
  15. }
  16.  
The program doesn't crash. I would like to know why the first version of function_3 with the call to function_2 crashes when called and why the second version, function_3_re_def with the dynamic memory allocation before the call to function_2_re_def, doesn't.

Is there a scope issue that means that you must know the size of an array before passing arrays into class member functions?

Thanks for your help.
Sep 16 '10 #1
Share this Question
Share on Google+
5 Replies


weaknessforcats
Expert Mod 5K+
P: 9,197
This code:

Expand|Select|Wrap|Line Numbers
  1. void class_name::function_2(double *mat) 
  2.    mat=new(double[(rows+1)*(cols+1)]); 
  3. etc...
doesn't do what you think.

mat is a local variable. It dies when the function completes. That is, mat is a copy of the original pointer.

Now if you need to change the address inside the original pointer and have that change visible in other functions, then you will need to pass the address of the original pointer:

Expand|Select|Wrap|Line Numbers
  1. void class_name::function_2(double **mat) 
  2.    *mat=new(double[(rows+1)*(cols+1)]); 
Sep 16 '10 #2

Oralloy
Expert 100+
P: 983
At the risk of being cheeky, how about passing as a reference to a pointer?

Expand|Select|Wrap|Line Numbers
  1. void class_name::function_2(double *&mat)
  2. {
  3.   mat = new double[(rows+1)*(cols+1)]
Then you can have happily confusing code that transparently assigns the outer pointer value.

BTW, this sort of memory management is interesting, but I would think that STL vectors are a much better choice in most instances.
Sep 16 '10 #3

weaknessforcats
Expert Mod 5K+
P: 9,197
You may pass a reference to a pointer.

What you save is making the copy of the pointer. However, underneath, the compiler implements a reference by using a pointer. That means you save nothing using a reference to a pointer.

What you should be using is a handle. Once you have allocated memory and pass that pointer around, you can't tell when it's safe to delete the allocation. It would only be safe if the pointer was the last copy in the program.

To keep track of the number of copies of the pointer you would need to implement reference counting.

You might read the C/C++ Insights article on using handle classes.
Sep 16 '10 #4

Oralloy
Expert 100+
P: 983
Yep.

I'm really unsure of what emaghero is trying to achieve.

If he wants reference counted dynamic arrays, he'll need to implement envelopes and include a reference count in the core object. Not difficult, actually, just tedious.

@emaghero - what is it you actully are trying to achieve?
Sep 16 '10 #5

emaghero
P: 85
Thanks for the replies.
Sep 19 '10 #6

Post your reply

Sign in to post your reply or Sign up for a free account.