0

EDIT: What if I'm trying to do it without global or static and without vector o dynamic vectors?

I'm trying to create two vectors and have a function that pass by address a new vector that is the quotient of each element of the two arrays. i.e. V1 is 1 1 2 2 3 4 V2 is 2 2 1 1 2 2 the result expected is 2 2 2 2 6 8

My problem is when I send the "r" result from the "quoziente" function because I receive random numbers. I think that the problem is that the function only exists during its execution but when it stops running it dies with his variables too. How should I do? I'm sure that I'm passing the right address to "ris". I tried even to print out the elements of the operation and I'm sure that I'm doing the right operation. Any help is really appreciated! Thanks

Here's the code:

  1 #include <iostream>
  2 using namespace std;
  3
  4
  5
  6 void readarray (int* v, int dim) { 
  7     for(int i=0; i<dim; i++) { 
  8         cin >> v[i];
  9     } 
 10 }
 11 
 12 void printarray(int* v, int dim) { 
 13     for(int i=0; i<dim; i++) { 
 14         cout << v[i] << " ";
 15     } 
 16     cout << endl;
 17 }
 18 
 19 int main() { 
 20     int v1[7];
 21     int v2[7];
 22     int *ris;
 23       
 24     cout << "V1";
 25     readarray(v1,7);
 26     cout << "V2";
 27     readarray(v2,7);
 28     ris = quoziente(v1,v2,7);
 29     cout << "V1";
 30     printarray(v1,7);
 31     cout << "V2";
 32     printarray(v2,7);
 33     cout << "ris ";
 34     printarray(ris,7);
 35     
 36     return 0;
 37 } 
 38 
 39 int* quoziente (int* v1, int* v2, int dim) { 
 40     int r[7]; 
 41 
 42     for(int i=0; i<dim; i++) { 
 43        r[i] = v1[i] * v2[i];
 44        cout << r[i] << " ";
 45     }
 46     cout << endl;
 47     return r;
 48 }
Adi Inbar
  • 12,097
  • 13
  • 56
  • 69
Giulio
  • 783
  • 7
  • 21
  • 3
    You can't return the address of a non-static local variable from a function. It is invalid as soon as it leaves scope and is therefore *undefined behavior* to dereference. Try passing an output array into the function as well. – WhozCraig Sep 02 '13 at 10:33

6 Answers6

5

This would be miles easier to manage if you used std::vector or other similar containers.

std::vector<int> quotient (std::vector<int> left, std::vector<int> right)
{ 
     std::vector<int> result;

     auto left_iterator = left.begin();
     auto left_end =  left.end();
     auto right_iterator = right.begin();
     auto right_end =  right.end();

     for(; left_iterator != left_end && right_iterator != right_end; 
         left_iterator++, right_iterator++) 
     { 
        int quotient = (*left_iterator) * (*right_iterator);
        result.push_back(quotient);
        std::cout << quotient << " ";
     }
     std::cout << std::endl;

     return result;
}

And of course as mentioned, there are also std::algorithm utilities more suitable for this too, such as std::transform - see P0W's answer. However, I'm guessing this is for your own learning, so looking into how std library containers in general work is also important.

  • +1 for using STL and mentioning the algorithms header. Maybe you can complete your answer be saying which algorithms are the most suitable... – Felix Dombek Sep 02 '13 at 11:02
3

You're right, because r is declared on the stack it will be deleted when it goes out of scope. You need to allocate memory on the heap e.g.

int *r = new int[7]; // * was missing

make sure you call delete [] ris; when you're done using it, to free the memory you allocated

Zoka
  • 2,312
  • 4
  • 23
  • 33
Matthew Mcveigh
  • 5,695
  • 22
  • 22
2

Inside your function quoziente(),

int r[7]; <-- This is allocated on stack, so it dies when the function returns.

Alternate ways to solve the problem:-

1) Allocate r dynamically inside quozinete().

int *r = new int [7];

2) Declare r as static.

static int r[7];

3) Put r in global scope.

4) Declare r in main along with v1 and v2 as:-

int v1[7];
int v2[7];
int r[7];

And change the prototype of quozinete as:-

void quoziente (int* v1, int* v2, int dim, int *r)

i.e. pass the pointer of result array to the function as another parameter.

Siddhartha Ghosh
  • 2,988
  • 5
  • 18
  • 25
  • +1 for listing all the ways, but you should add when each way is preferred. I.e., when you do not need r outside of the main function, (4) would be the logical way, but if you do, (1) is better. – Felix Dombek Sep 02 '13 at 11:00
  • @FelixDombek The only acceptable solution here is (4). But of course, this is why we have `std::vector` and `std::array`. Even (4) is awkward. – James Kanze Sep 02 '13 at 12:09
1

for example make r look like this:

int *r = new int[7];

But you must delete it later.

Or make it static

static int r[7];

and you do not have to delete. But it is shared along all function calls, therefore you may not call it twice, keep the pointer and expect the result remains the same.

Zoka
  • 2,312
  • 4
  • 23
  • 33
1

You might have already figured out the problem by others answers

I'll just show you another way to achieve the same thing using STL algorithm

std::transform and a lambda function

  int v1[7];
  int v2[7];
  int ris[7];

  std::transform(std::begin(v1), std::end(v1), 
             std::begin(v2), 
              std::begin(ris),
           [](const int &x, const int &y){ return x*y;}
                      );

SEE DEMO

Community
  • 1
  • 1
P0W
  • 46,614
  • 9
  • 72
  • 119
1

As reason explained in other answers array you define in the function is temperary. It exist till function exist. Different way to solve this problem is to define an array named ris rather than pointer, of size same to other two arrays v1 and v2. Pass it as argument to the function and change the function to

void quoziente (int* r, int* v1, int* v2, int dim) {  
  for(int i=0; i<dim; i++) { 
    r[i] = v1[i] * v2[i];
   cout << r[i] << " ";
 }
}

Pass res as argument while calling function quoziente

quoziente(ris,v1,v2,7)

Second solution solution is to allocate array dynamically using new operator as already explained in other answers. But remember to delete the array when it would not been in use in main function. And this not recommended practice, since there is no way of knowing that we have to delete array in main() function, if you do not have access to function code. And even if you have access to function you generally forget to delete it.

Third solution of declaring the variable/array static is also not recommended, since if you reuse the function for different array allocation, previous allocated array would be changed too.

Himanshu Pandey
  • 726
  • 5
  • 13