-2

I want to have a function that creates an array contain multiplication values of int num, and another function that prints the array out. However, I can't seen to figure out these errors.

My code:

.c file

#include "multiplication.h"
#include <stdio.h> 
int main(){
int arr=multiplication(4);
printArray(4,arr);



}

int multiplication(int num){
 /* initialize array and build*/
    int arr[num][num];
    for(int i=0; i<num;i++){
        printf("row number: %d ",i);
         for(int j=0;j<num;j++){
             printf("column number: %d", j);
            arr[i][j]= (i+1)*(j+1);
         }
    }
    return arr;
    }

    void printArray(int num,int arr[num][num]){
    
    int i;
    for(i=0;i<num;i++){
        for(int j=0;j<num;j++){
            printf("%d ",arr[i][j]);
        }
        
    }
    }

.h file:

int multiplication(int num);
void printArray(int num,int arr[num][num]);

The errors:

multiplication.c:6:14: warning: incompatible integer to pointer conversion passing 'int' to parameter of type 'int (*)[*]' [-Wint-conversion]
printArray(4,arr);
             ^~~
./multiplication.h:4:29: note: passing argument to parameter 'arr' here
void printArray(int num,int arr[num][num]);
                            ^
multiplication.c:22:12: warning: incompatible pointer to integer conversion returning 'int [num][num]' from a function with result type 'int' [-Wint-conversion]
    return arr;
           ^~~
multiplication.c:22:12: warning: address of stack memory associated with local variable 'arr' returned [-Wreturn-stack-address]
    return arr;
           ^~~

                    ^
multiplication.c:25:33: note: declared here
    void printArray(int num,int arr[num][num]){
                            ^
Jake
  • 1
  • 2
  • You have `int mulitpication(int num){` and call `int arr=multiplication(4);` — these are two different functions (`mulit` vs `multi`). You can't (usefully) return a local array but the code in `mulitpication()` appears to do so. – Jonathan Leffler Sep 17 '20 at 16:30
  • 1
    `int arr = ...` in `main` declares `arr` as a simple `int`. Despite the name it's not an array. – user3386109 Sep 17 '20 at 16:31
  • @user3386109 I thought you had to declare a 2D array using "int" and then brackets ([][]) afterwards. – Jake Sep 17 '20 at 16:36
  • @JonathanLeffler What you mean by I can't usefully) return a local array but the code in mulitpication() appears to do so? How would you return an array? – Jake Sep 17 '20 at 16:38
  • @Jake Yes, that's correct. And the declaration of `arr` in `main` doesn't do that. – user3386109 Sep 17 '20 at 16:39
  • Since the array goes out of scope once the function returns, it is no longer valid once the calling function resumes execution. Therefore, there is no point in returning the pointer to a now non-existent array. Hence the term 'can't (usefully) return'. You can return a pointer (the starting address of the array) — though your function claims it returns an `int`, another problem. But it has to be a pointer to data that is still valid to be useful. Dynamic memory allocation (`malloc()` et al) is one option; the other is to pass the array into the function, but then, what is the right size? – Jonathan Leffler Sep 17 '20 at 16:40
  • Ah, I see. It should be "int arr[][]=multiplication(4);", correct? – Jake Sep 17 '20 at 16:41
  • Does this answer your question? [How to return a 2D array from a function in C?](https://stackoverflow.com/questions/5201708/how-to-return-a-2d-array-from-a-function-in-c) – Abra Sep 17 '20 at 16:42
  • No. You need to create `int arr[4][4];` in `main()` and call `multiplication(4, arr)` and modify the interface to `void multiplication(size_t size, int arr[size][size]) { ... }` or thereabouts. – Jonathan Leffler Sep 17 '20 at 16:42
  • @Jake No, the return type of the **multiplication()** should be of `int **` type. – Shubham Sep 17 '20 at 16:43
  • 1
    It should be `int num = 4;` `int arr[num][num];` `multiplication(num, arr);` Similar to what you did with `printArray`. It's best to pass the array to the function, rather than trying to have the function return an array. – user3386109 Sep 17 '20 at 16:44
  • @JonathanLeffler So I understand the first part of your comment, but i'm lost on the second part. If I change multiplication to void, how can I turn a value? Also, wouldn't the parameter size be an integer in this case? – Jake Sep 17 '20 at 16:51
  • @user3386109 I understand, so your suggesting that I initialize the array BEFORE passing it in. That a good idea! Honestly, you guys a big help! – Jake Sep 17 '20 at 16:53
  • You modify the array passed to the function, rather than creating the array in the function and returning it. So there's no need for a `return` statement. Life gets messy if you really _must_ return a pointer to a variably modified array — I'd rather not get involved in that. So, to avoid such complications without passing the array into the function, you'd probably end up returning a 1D dynamically allocated array that can, if you're careful, be treated like a 2D array. But passing the array into the function is almost certainly the best option. – Jonathan Leffler Sep 17 '20 at 16:54
  • would I be passing in the array into multiplication function if the parameters were set to : "int multiplication(int num,int arr[num][num]){...}" – Jake Sep 17 '20 at 17:30
  • Yes. You'd call `multiplication(4, arr);` after defining `int arr[4][4];`. That passes the array (and its size) to the function. – Jonathan Leffler Sep 17 '20 at 17:32
  • @JonathanLeffler So the code works, however I did get the following warning error: "multiplication.c:19:12: warning: incompatible pointer to integer conversion returning 'int (*)[num]' from a function with result type 'int' [-Wint-conversion] return arr;" What does this mean? – Jake Sep 17 '20 at 17:53
  • It appears to mean you did not change the type of `multiplication()` from `int` to `void` and you still tried to return something from the function. Details matter. If the function accepts the array as an argument, there is no good reason to return a value from the function. – Jonathan Leffler Sep 17 '20 at 17:55
  • But don't you want to return the modified array? Say I wanted to return the array value and place it into an array variable newArray in main(). Would I want to return the array to place it in that variable? – Jake Sep 17 '20 at 18:06

2 Answers2

0

Your code is one big Undefined Behaviour.

int mulitpication(int num)

  1. You want to return a pointer to int. But it is declared int not int *. When you try to return the pointer, the compiler warns you about incompatible conversion
  2. Even if you declare it as returning pointer you return a pointer to an automatic variable which ceases to exist when the function returns (warning about stack variable).

void printArray(int num,int arr[num][num])

  1. sizeof returns the size of the pointer not the size of the array

main function.

  1. arr is a single integer and you try to pass to print function. You need to make it int *
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
0___________
  • 60,014
  • 4
  • 34
  • 74
  • I'm confused on what you mean in your last statement. You saying I should make it "int *arr[num][num]"? @P__J__ – Jake Sep 17 '20 at 17:18
0

This is what I regard as the code you need:

#include <stdio.h>

static void multiplication(int num, int arr[num][num]);
static void printArray(int num, int arr[num][num]);

int main(void)
{
    int arr[4][4];
    multiplication(4, arr);
    printArray(4, arr);

    return 0;
}

static void multiplication(int num, int arr[num][num])
{
    for (int i = 0; i < num; i++)
    {
        //printf("row number: %d ", i);
        for (int j = 0; j < num; j++)
        {
            //printf("column number: %d", j);
            arr[i][j] = (i + 1) * (j + 1);
            printf("arr[%d][%d] = %d\n", i, j, arr[i][j]);
        }
    }
}

static void printArray(int num, int arr[num][num])
{
    int i;
    for (i = 0; i < num; i++)
    {
        for (int j = 0; j < num; j++)
        {
            printf("%d ", arr[i][j]);
        }
        putchar('\n');
    }
}

The output from running that is:

arr[0][0] = 1
arr[0][1] = 2
arr[0][2] = 3
arr[0][3] = 4
arr[1][0] = 2
arr[1][1] = 4
arr[1][2] = 6
arr[1][3] = 8
arr[2][0] = 3
arr[2][1] = 6
arr[2][2] = 9
arr[2][3] = 12
arr[3][0] = 4
arr[3][1] = 8
arr[3][2] = 12
arr[3][3] = 16
1 2 3 4 
2 4 6 8 
3 6 9 12 
4 8 12 16 

You can ring the changes in main(), for example getting a size from the user and creating an array of that size and passing the info to the functions:

int size;
if (scanf("%d", &size) == 1 && size > 0 && size < 100)
{
    int other[size][size];
    multiplication(size, other);
    printArray(size, other);
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • You modify the array using the multiplication function, but you don't return the result into another variable in the function, say NewArray. How does printArray know to print the same array if you don't assign the return value as a parameter? – Jake Sep 17 '20 at 18:27
  • The array was passed ”by reference”, not by value. Changes made in the function changed the array defined in `main()`. This is normal in C. Arrays are passed ”by reference” and changes made in the called function change the array in the calling function. – Jonathan Leffler Sep 17 '20 at 18:30
  • OOOOH, ok. Thanks for that. I'm new to C so i'm still learning. Is this only true for arrays? – Jake Sep 17 '20 at 18:35
  • Yes. Arrays are passed ”by reference”, meaning that a pointer to the start of the array is passed to the function. The data is not copied, but by referencing the pointer (indexing the array) in the called function, you modify the array in the calling function. Other types, including structures and unions, are passed by value, meaning that a copy of the data is passed to the called function. Unless, of course, you pass a pointer to the structure or union. That is the normal regime for C. I'm not sure there is an abnormal regime to worry about unless you use another language such as C++. – Jonathan Leffler Sep 17 '20 at 18:40