-1

The purpose of this exercise is to use the two-subscript method of dynamic memory allocation. Input for this program is a two-dimensional array of floating point data located in a file named testdata2. The input array will contain 3 rows of data with each row containing 5 columns of data.

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

int main()
{
    FILE *fp;
    int temp;
    int number;
    int r = 3;
    int c = 5;

    fp = fopen("testdata2.txt", "r");

    number = (int)malloc(r * c * sizeof(int));

    while (fscanf(fp, "%d", &temp) != EOF){
        for(int i = 0; i < 3;i++){
            for(int j = 0; j < 5; j++){
                temp = number[i][j];
            }
        }   
    }   

    return(0);
}
Gaurav Pathak
  • 1,065
  • 11
  • 28
  • 1
    The "subscripted value" the error message is referring to is `number`. `number` has type `int`, you cannot test it as an array (in `temp = number[i][j];`). – pmg Apr 10 '17 at 15:29
  • 1
    `number = (int)malloc(r * c * sizeof(int));` if there were a more concrete example of incorrectly masking warnings with a cast, we'd be hard pressed to find it. – WhozCraig Apr 10 '17 at 15:30
  • 1
    Also Use `float` or `double` for _floating point data_. – BLUEPIXY Apr 10 '17 at 15:37

4 Answers4

1

Among the plethora of things incorrect in your code (any one of which can result in undefined behavior):

  1. The core data type is wrong. The question specifically calls for floating-point values, yet you're using integer types.
  2. The receiver of any memory allocation in C should be a pointer; you're using a simple int.
  3. You're hiding whatever warnings/errors you're receiving by hard-casting. Casting malloc in C isn't necessary, nor advised.
  4. Even if everything else were fixed, your assignment statement for temp = ... is backward. You want to save the value just-read into your matrix, not throw it away and overwrite it with whatever undefined value resides in your memory-just-allocated.

All of that said, knowing the width of your array of arrays is five, the problem reduces to this. Note temp isn't needed at all

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

int main()
{
    static const size_t r = 3;
    static const size_t c = 5;

    FILE *fp = NULL;
    double (*number)[c] = NULL; // pointer to array of dimension c.

    fp = fopen("testdata2.txt", "r");
    if (fp == NULL)
    {
        perror("Failed to open file: ");
        return EXIT_FAILURE;
    }

    number = malloc(r * sizeof *number); // allocate r-rows of dimension c
    if (number == NULL)
    {
        perror("Failed to allocate array of arrays: ");
        return EXIT_FAILURE;
    }

    for (size_t i=0; i<r; ++i)
    {
        for (size_t j=0; j<c; ++j)
        {
            if (fscanf(fp, "%lf", number[i]+j) != 1)
            {
                fprintf(stderr, "Failed to parse int at %zu,%zu", i, j);
                return EXIT_FAILURE;
            }
        }
    }

    for (size_t i=0; i<r; ++i)
    {
        for (size_t j=0; j<c; ++j)
            printf("%lf ", number[i][j]);
        fputc('\n', stdout);
    }

    free(number);

    return(0);
}
WhozCraig
  • 65,258
  • 11
  • 75
  • 141
0

You are declaring an integer:

int number;

and you are allocating memory with malloc assuming it is a multi-dimensional array, then trying to access its elements in the same way. Change the declaration to:

int **number;
  • That's not enough. You still can't use `number[i][j]` – JeremyP Apr 10 '17 at 15:37
  • That's not enough... he's trying to index it as either a 2D array or an array of pointers. `int **number;` would work as an array of pointers, but he'd have to allocate an array of `r` pointers and then allocate `r` arrays of `c` `int`s assigned to each for that. He could also use `int (*number)[c] = malloc(r * c * sizeof(int));` (once `c` and `r` are known) and allocate a real 2D array. – Dmitri Apr 10 '17 at 15:38
  • Then he has to add: number= (int **)malloc(r * sizeof(int *)); for (i=0; i – Mohammed Bakr Sikal Apr 10 '17 at 15:39
  • or even with one malloc for all rows number = (int **)malloc(sizeof(int *) * r); and then for each element number[0] = (int *)malloc(sizeof(int) * c * r); – Mohammed Bakr Sikal Apr 10 '17 at 15:42
0

it is not

(int)malloc(rcsizeof(int))

It is

(int*) malloc(rcsizeof(int))

One more mistake is that you can't access the elements as

temp=number[i][j];

Replace it with

temp=number[i*r+j]

Hope this helps

0
number = (int)malloc(r * c * sizeof(int));

In C, never cast the result of a malloc. If you had left out the cast to int, you'd have a diagnostic here telling you that number is not a pointer type.

You can do this:

int* number = malloc(r * c * sizeof(int));

But that gives you one big single dimensional array. You would need to dereference it like this:

temp = number[i * c + j];

If you want two dimensional indices as if you had declared it like this:

int number[r][c];

you need to allocate it in two stages:

int** number = malloc(r * sizeof(int*));
number[0] = malloc(r * c * sizeof(int));
for (int i = 1 ; i < r ; i++)
{
    number[i] = &number[0][i * c];
}

That sets up a big array of ints and an intermediate array of pointers to ints for each row. Now you can do

temp = number[i][j];

Edit

Or you can do what Dmitri says which is this:

int (*number)[c] = malloc(r * c * sizeof(number[0][0]));

That effectively mallocs an array of r blocks of c ints in one go.

JeremyP
  • 84,577
  • 15
  • 123
  • 161
  • 1
    The dynamically allocated equivalent to `int number[r][c];` is not what you've shown... try `int (*number)[c] = malloc(r * c * sizeof(number[0][0]));`, which allocates it as a single block containing a 2D array, having the same layout as the non-dynamic version and not relying on an array of row pointers. – Dmitri Apr 10 '17 at 15:49
  • @Dmitri Excellent thanks. – JeremyP Apr 10 '17 at 15:51