0

I am trying to create a 2D array where the values are taken as command line arguments.

The 2D array will always be a square with the side length being the first command line argument.

I can create the individual arrays fine, however it seems like creating one is getting rid of the previous one as when I check the array of arrays it is made up of the same array 3 times.

My code is as follows:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
        int squareSize = atoi(argv[1]);
        int *matrix[sizeof(int) * squareSize];
        for(int i = 0; i < squareSize; i++) {
                int line[sizeof(int) * squareSize];
                int *lPointer = &line[0];
                for(int j = 0; j < squareSize; j++) {
                        *lPointer = atoi(argv[i*squareSize + j + 2]);
                        lPointer++;
                }
                printf("L: %d ", line[0]);
                printf("%d ", line[1]);
                printf("%d\n", line[2]);
                matrix[i] = line;
        }

        printf("M: %d ", matrix[0][0]);
        printf("%d ", matrix[0][1]);
        printf("%d ", matrix[0][2]);
        printf("%d ", matrix[1][0]);
        printf("%d ", matrix[1][1]);
        printf("%d ", matrix[1][2]);
        printf("%d ", matrix[2][0]);
        printf("%d ", matrix[2][1]);
        printf("%d\n", matrix[2][2]);

        return(0);
}

Command line input: ./filename 3 1 2 3 4 5 6 7 8 9

Expected output:

L: 1 2 3
L: 4 5 6
L: 7 8 9
M: 1 2 3 4 5 6 7 8 9

Actual output:

L: 1 2 3
L: 4 5 6
L: 7 8 9
M: 7 8 9 7 8 9 7 8 9

Does anyone know how to prevent new arrays that I create from replacing the last?

13
  • 2
    Your int *matrix[sizeof(int) * squareSize] is an array of some number of pointers. 2D array should contain squareSize² int elements. Commented Oct 15, 2022 at 20:22
  • 1
    You have matrix[i] = line; but line has gone out of scope before you report on matrix. Even if if didn't, the loop does not create independent/distinct line variables. Commented Oct 15, 2022 at 20:22
  • @dimich thank you, that makes sense. It doesn't fix the issue though Commented Oct 15, 2022 at 20:24
  • @WeatherVane nah, it's still within the scope. Line is declared inside the outer for loop Commented Oct 15, 2022 at 20:25
  • 1
    By using malloc. Commented Oct 15, 2022 at 20:33

2 Answers 2

1

If squareSize is fairly small, use a simple Variable Length Array.
Use it the same as matrix[3][3].

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    int squareSize = atoi(argv[1]);
    int matrix[squareSize][squareSize];
    for(int i = 0; i < squareSize; i++) {
        for(int j = 0; j < squareSize; j++) {
            matrix[i][j] = atoi(argv[i*squareSize + j + 2]);
        }
    }

    printf("M: %d ", matrix[0][0]);
    printf("%d ", matrix[0][1]);
    printf("%d ", matrix[0][2]);
    printf("%d ", matrix[1][0]);
    printf("%d ", matrix[1][1]);
    printf("%d ", matrix[1][2]);
    printf("%d ", matrix[2][0]);
    printf("%d ", matrix[2][1]);
    printf("%d\n", matrix[2][2]);

    return(0);
}  

input: ./filename 3 1 2 3 4 5 6 7 8 9

output: M: 1 2 3 4 5 6 7 8 9

Sign up to request clarification or add additional context in comments.

Comments

0

The smallest change is to allocate a new line per loop iteration (free left out as exercise for reader):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
    int squareSize = atoi(argv[1]);
    int *matrix[sizeof(int) * squareSize];
    for(int i = 0; i < squareSize; i++) {
        int *line = malloc(sizeof(int) * squareSize);
        int *lPointer = line;
        for(int j = 0; j < squareSize; j++) {
            *lPointer = atoi(argv[i*squareSize + j + 2]);
            lPointer++;
        }
        printf("L: %d ", line[0]);
        printf("%d ", line[1]);
        printf("%d\n", line[2]);
        matrix[i] = line;
    }
    printf("M: %d ", matrix[0][0]);
    printf("%d ", matrix[0][1]);
    printf("%d ", matrix[0][2]);
    printf("%d ", matrix[1][0]);
    printf("%d ", matrix[1][1]);
    printf("%d ", matrix[1][2]);
    printf("%d ", matrix[2][0]);
    printf("%d ", matrix[2][1]);
    printf("%d\n", matrix[2][2]);

    return(0);
}

and it now returns the expected result:

L: 1 2 3
L: 4 5 6
L: 7 8 9
M: 1 2 3 4 5 6 7 8 9

Here's a refactored version with error checking and just stores the data directory into a int matrix[squareSize][squareSize] variable and using separate function to print the matrix:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// offset into argv where the data starts
#define OFFSET 2

void printSquareMatrix(int n, int matrix[n][n]) {
    const char *delim = " \n";
    printf("M: ");
    for(int row = 0; row < n; row++)
        for(int col = 0; col < n; col++)
            printf("%d%c",
                matrix[row][col],
                delim[row + 1 == n && col + 1 == n]
            );
}

int main(int argc, char *argv[]) {
    if(argc < 2) {
        printf("usage: %s size data*(size^2)\n", *argv);
        return 0;
    }
    int squareSize = atoi(argv[1]);
    if(squareSize * squareSize != argc - 2) {
        printf("incorrect number of data items\n");
        return 1;
    }
    int matrix[squareSize][squareSize];
    for(int row = 0; row < squareSize; row++) {
        for(int col = 0; col < squareSize; col++) {
            matrix[row][col] = atoi(argv[OFFSET + row*squareSize + col]);
        }
    }
    printSquareMatrix(squareSize, matrix);
}

and the output is now just:

M: 1 2 3 4 5 6 7 8 9

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.