-3

I'm trying to open a file that has dimensions and values for two matrices. I want to store the dimensions of the matrices, and create three 2D int arrays with those read from the file (the third is the result of matrix multiplication). I'm passing a pointer to an int pointer for the argument, hence why the parameters for the read_matrices method are int** (assignment requirement).

I keep getting a segmentation fault during the malloc portion of my code, but can't figure out the problem. It seems to work for the first two matrices, and I can get the first printf statement to print during the malloc for array3, but I get a segmentation fault before the second printf statement. I assume there's something wrong in the loop, but I can't figure it out, especially because it seems to work for the malloc of array1 and array2 (unless the whole thing is wrong). Any help is appreciated.

Edit: Edited to include only the most important portions of the code

void read_matrices(int **array1, int **array2, int **array3, int *m, int *n, int *p, char* file)
{

   /* Get the size of the matrices */
    fscanf(fp, "%d", m);
    fscanf(fp, "%d", n);
    fscanf(fp, "%d", p);

    /* Use malloc to allocate memory for matrices/arrays A, B, and C */
    array1 = (int**) malloc(*m * (sizeof(int*)));

    for (i = 0; i < *m; i++)
    {
        *(array1 + i) = (int*) malloc(*n * (sizeof(int)));
    }


    array2 = (int**) malloc(*n * (sizeof(int*)));

    for (i= 0; i < *n; i++)
    {
        *(array2 + i) = (int*) malloc(*p * (sizeof(int)));
    }


    array3 = (int** ) malloc(*m * (sizeof(int*)));

    for (i= 0; i < *m; i++)
    {
        *(array3 + i) = (int *) malloc(*p * (sizeof(int)));
        printf("Going through malloc3 loop\n");
    }
    printf("End of the third part of malloc\b");

    /* Close the stream */
    fclose(fp);
}

int main (int argc, char *argv[])
{
    /* Int pointers to three matrices */
    int *A, *B, *C;

    /* Int variables to store matrix dimensions */
    int m, n, p;

    /* Get the name of the file */
    char* filename = *(argv + 1);

   /* Read the matrices and fill matrices A and B */
    read_matrices(&A, &B, &C, &m, &n, &p, filename);

    /* Exit the system */
    return 0;
}
  • Please provide a [mcve]; see also https://ericlippert.com/2014/03/05/how-to-debug-small-programs/. – melpomene Sep 29 '19 at 16:53
  • Your `mult_matrices(A, B, C, m, n, p)` call has undefined behavior due to https://stackoverflow.com/q/1398307/1848654 / https://stackoverflow.com/q/766893/1848654. – melpomene Sep 29 '19 at 16:55
  • So I'm a little confused. I thought for a 2D array, I could define it as an int* in main, pass by reference using the & operator, and then receive it as a pointer in the read_matrices method. Am I defining the 2D array incorrectly in main, or is it how I'm using malloc? Sorry! I'm very new to C – remindmyself Sep 29 '19 at 17:00
  • 1
    This code does not even compile. Therefore it cannot produce a segmentation fault. – klutt Sep 29 '19 at 17:01
  • Did you read the linked questions and answers? – melpomene Sep 29 '19 at 17:01
  • So the code doesn't compile because a lot of code has been removed, as requested by mepomene. For mepomene, I did read the posts, but I'm very confused. Everything I've looked at on how to allocate for a 2D array is very different than what is listed in those posts. – remindmyself Sep 29 '19 at 17:09
  • I did not request you remove half of your code. Your initial post was already incomplete (e.g. all of your `#include`s and half of your functions were missing). The point is to make your problem *reproducible* (in the smallest amount of code). If I can't compile your program, I can't reproduce anything. – melpomene Sep 29 '19 at 17:12
  • Jon, " I thought for a 2D array, I could define it as an int* in main" --> there is no 2D array in this code. `int foo[6][7]` is a 2D array. `array1` is a [pointer to pointer to int](https://cdecl.org/?q=int+**array1). A pointer is not an array. An array is not a pointer. – chux - Reinstate Monica Sep 29 '19 at 17:16

1 Answers1

0

To allocate memory for A[m][n] a pointer to pointer can be used int **A;
The difference in allocation is in the rows and columns. One function can be used for each of the three pointers.
Another function can be added to read values from a file. That function will need the pointer, rows, columns and the file pointer.

#include <stdio.h>
#include <stdlib.h>
int get_size ( void)
{
    char input[100] = "";
    int size = 0;
    int result = 0;
    do {
        if ( fgets ( input, sizeof input, stdin)) {
            result = sscanf ( input, "%d", &size);
        }
        else {
            fprintf ( stderr, "fgets EOF\n");
            exit ( 0);
        }
    } while ( 1 != result || 0 >= size);
    return size;
}
int **free_matrice ( int **array, int row)
{
    for ( int i = 0; i < row; i++)
    {
        free ( array[i]);
    }
    free ( array);

    return NULL;
}
int **create_matrice ( int row, int col)
{
    int **array1 = NULL;
    /* Use malloc to allocate memory for matrices/arrays A, B, and C */
    if ( NULL == ( array1 = malloc ( sizeof(int*) * row))) {
        fprintf ( stderr, "problem malloc\n");
        exit ( 0);
    }
    for ( int i = 0; i < row; i++)
    {
        if ( NULL == ( array1[i] = malloc ( sizeof(int) * col))) {
            fprintf ( stderr, "problem malloc\n");
            exit ( 0);
        }
    }

    return array1;
}

int main (int argc, char *argv[])
{
    /* Int pointers to three matrices */
    int **A, **B, **C;

    /* Int variables to store matrix dimensions */
    int m = 0, n = 0, p = 0;

    printf ( "enter size for m\n");
    m = get_size ( );
    printf ( "enter size for n\n");
    n = get_size ( );
    printf ( "enter size for p\n");
    p = get_size ( );

    A = create_matrice ( m, n);
    B = create_matrice ( n, p);
    C = create_matrice ( m, p);

    A = free_matrice ( A, m);
    B = free_matrice ( B, n);
    C = free_matrice ( C, m);

    return 0;
}
user3121023
  • 8,181
  • 5
  • 18
  • 16