0

I'm busy with an assignment, but I'm not sure how to tackle a problem. As a part of a program I need to write an add function. The goal of the program is to:

  • Read two integer values n1 and n2 from the command line.

  • Allocate two integer arrays array1 and array2 of size n1 and n2

  • inititalize the two arrays with values 0,1....,n1-1 and 0,1....,n2-1

  • Write an add function with the signature:

    void add(... array1, ... n1, ... array2, ... n2, ... array3, ... n3)

The function should provide the following functionality:

  • Allocates an interger array array3 of size n3 = max(n1,n2);
  • adds the two arrays array1 and array2 element by element into array3;
  • adds only the first min(n1,n2) elements and copies the elements from the longer array when the two arrays have different length;
  • returns array3 and its length n3 via the fifth and the sixth function argument, respectively. Do not change the signature of the add function.

I'm stuck at the part of the add function. I don't see how array3 must be an input argument, but also needs to be allocated in the function. The same confusion holds for n3.

I got as hint that I need to work with double pointers.

Question: How can I implement the first functionality point of the function, while keeping the function signature the same?

Many thanks in advance :) Nadine

EDIT:

My code so far:

// Include header file for standard input/output stream library
#include <iostream>

// Your implementation of the add functions starts here...

void add(int *array1, int *array2, int **array3){
    array1[5] = 20;
}


// The global main function that is the designated start of the program
int main(int argc,char* argv[]){


    // Read integer values n1 and n2 from the command line
    //int n1;
    //int n2;
    //n1 = atoi(argv[1]);
    //n2 = atoi(argv[2]);

    

    // Allocate and initialize integer arrays array1 and array2
   int n1 = 10;
   int n2 = 10;

   int* array1  = NULL;
   array1  = new int[n1];

   int* array2  = NULL;
   array2  = new int[n2];
   

   for (int x = 0; x<n1; x++)
   {
       array1[x] = x;
   }
   
   for (int y = 0; y<n2; y++)
   {
       array2[y] = y;
   }


   int *array3;

    // Test your add function

   add(array1, array2, &array3);
  
   
    delete[] array1;
    delete[] array2; 
    delete[] array3;

  
    

    // Return code 0 to the operating system (= no error)
    return 0;
}
janw
  • 8,758
  • 11
  • 40
  • 62
Nadine
  • 51
  • 6
  • 1
    My advice is to break the problem down into parts you understand. – drescherjm Nov 15 '20 at 15:55
  • 1
    The preferred `c++` way of allocating a dynamic array is to use `std::vector` – drescherjm Nov 15 '20 at 15:56
  • 1
    Though its not the preferred type of school intro courses.. @drescherjm – sagi Nov 15 '20 at 15:58
  • 1
    Incompetent teaching. Instead of teaching `c++` still teaching c with classes which should have been abandoned 2+ decades ago. – drescherjm Nov 15 '20 at 15:58
  • 1
    When there is confusion about the assignment's requirements, _talk to the person who gave it to you_. Just _have a conversation_ with your teacher. There is no need to go to strangers on the internet and hope that they can guess what your teacher wanted. – Asteroids With Wings Nov 15 '20 at 16:03
  • Looks like straight C, not C++. Are you sure it's a C++ class? – doug Nov 15 '20 at 16:36
  • @doug Yes, the course is called object oriented programming with c++. – Nadine Nov 15 '20 at 16:51
  • While you're learning c++ with a formal course, you should pick up a more modern intro book that will provide insight about how c++ coding practice has evolved. This site has a list here: https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list/388282#388282 – doug Nov 15 '20 at 18:03

2 Answers2

4

You need to allocate the array inside the function, but also return the allocated array through the "output parameter" array3. To return something through an output parameter, the parameter needs to be a pointer; but to return an array, the array itself is also a pointer. So what we need is indeed a pointer to a pointer:

void add(... array1, ... n1, ... array2, ... n2, int **array3, ... n3)

It would be called like this:

// Caution: uninitialized pointer at this point! Do not dereference!
int *output;
// Pass the address of the pointer.
add(..., ..., ..., ..., &output, ...);
// Now output has been initialized, so *output is valid (same as output[0]).

output is a single pointer because it contains the address of the array.

When passing this to the function add, we write &output instead of simply output. You can read this as "address of output", which is the address of the pointer, which is the address of the address of the array. This way, add can write into the pointed-to variable.

Inside add, you could do something like this to allocate the array:

*array3 = new int[n3];

Notice the extra * here: we want to store the address of the newly allocated array in the location pointed to by array3, not in array3 itself (which, after all, does not point to an array but to a pointer).


All this might become a bit easier to understand if the function returned a single float instead of an int *:

void approximate_pi(float *out) {
    *out = 3.14;
}

int main() {
    float pi;
    approximate_pi(&pi);
}

The function accepts a pointer to a float, and writes the output into the location that the pointer points to. When calling the function, we pass the address of the desired output location.

Thomas
  • 174,939
  • 50
  • 355
  • 478
  • References would work too, and might avoid some double pointer confusion. Although reading the question again, the OP has been more or less told they should use a double pointer. – john Nov 15 '20 at 16:10
  • The question said "I got as hint that I need to work with double pointers." There's something to be said for pointers here: it's clear at the call site from the extra `&` that the argument is not passed by value or by const reference, so it might be mutated by the function. – Thomas Nov 15 '20 at 16:12
  • @Nadine I expanded my answer a bit, hope that helps! – Thomas Nov 16 '20 at 09:52
  • @Thomas Yes, I think I understand it more. Thanks! – Nadine Nov 16 '20 at 18:04
0
// I am also doing that course, here is my code
// I past current self-test
// But I mistakenly clicked spec test twice before, so I only get one chance left
// Could you try the spec test on your Weblab and let me know the result?

// Include header file for standard input/output stream library
#include <iostream>
// Your implementation of the add functions starts here...
void add(int* array1, int n1, int* array2, int n2, int** array3, int& n3)
{
    n3 = std::max(n1, n2);
    *array3 = new int[n3];
    for (int i=0; i<n3; i++)
    {
        if (i >= n1) {*(*array3+i) = array2[i];}
        else if (i >= n2) {*(*array3+i) = array1[i];}
        else {*(*array3+i) = array1[i] + array2[i];}  
    }
}

// The global main function that is the designated start of the program
int main()
{
    // Read integer values n1 and n2 from the command line
    int n1 = 9;
    int n2 = 10;

    // Allocate and initialize integer arrays array1 and array2
    int* array1 = new int[n1];
    for (int i =0; i<n1; i++) {*(array1+i) = i;}
    int* array2 = new int[n2];
    for (int i =0; i<n2; i++) {*(array2+i) = i;}
    int* array3 = NULL;
    int n3 = 0;

    // Test your add function
    add(array1, n1, array2, n2, &array3, n3);
    std::cout<<"Array3 = " << std::endl;
    for (int i=0; i < n3; i++) {std::cout<<array3[i]<<std::endl;}
    std::cout<<"The length of array3 = "<< n3 << std::endl;
    delete[] array1, 
    delete[] array2;
    delete[] array3;
    array1 = nullptr;
    array2 = nullptr;
    array3 = nullptr;
    // Return code 0 to the operating system (= no error)
    return 0;
}