Search code examples
csegmentation-faultdynamic-memory-allocation

Memory allocation and table reading using scanf()


I want to read two dynamically allocated tables, one 1dim (k) and one 2dim (c) and I get segmentation fault 11.

My code:

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

int main (void){
    int *number_of_models, **cost, budget, number_of_products, i, j;
    
    scanf("%d %d", &budget, &number_of_products);
    
    number_of_models = malloc (number_of_products * sizeof(int));
    if (number_of_models == NULL){
        return -1;
    }
    cost = malloc (number_of_products * sizeof(int*));
    if (cost == NULL){
        return -1;
    }
    for (i = 0; i < number_of_products; i++){
        scanf("%d", &number_of_models[i]);          // Read number of available models for product i
        cost[i] = malloc (number_of_models[i] * sizeof(int));
        if (cost[i] == NULL){
            return -1;
        }
        for (j = 0; j < number_of_models[i]; j++){
            scanf("%d", &cost[i][j]);       // Read the cost of j-th model of product i
        }
    }

    return 0;
}

It crashes when I try to scan c[0][1].


Solution

  • OP's code is well formelted, has some error checking yet lacks input error checking and meaningful object names.

    I suspect the issue is missing includes, as that would mess up the function calls. Allocations look OK, yet could be improved.

    Below is an attempt for clean up.

    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void) {
      //int *k, **c, m, n, r = 0, i, j;
      int m; // m's use is unclear.
      size_t rows;
    
      if (scanf("%d %zu", &m, &rows) != 2) {
        fprintf(stderr, "Failure to read sizes.\n");
        return -1;
      }
    
      // k = malloc (n * sizeof(int));
      size_t *columns_per_row = malloc(sizeof *columns_per_row * rows);
      if (columns_per_row == NULL) {
        fprintf(stderr, "Out of memory %d.\n", __LINE__);
        return -1;
      }
      // c = malloc (n * sizeof(int*));
      int **c = malloc(sizeof *c * rows);
      if (c == NULL) {
        fprintf(stderr, "Out of memory %d.\n", __LINE__);
        return -1;
      }
    
      //for (i = 0; i < n; i++){
      for (size_t row = 0; row < rows; row++) {
        if (scanf("%zu", &columns_per_row[row]) != 1) {
          fprintf(stderr, "Failure to read column size.\n");
          return -1;
        }
        c[row] = malloc(sizeof c[row][0] * columns_per_row[row]);
        if (c[row] == NULL) {
          fprintf(stderr, "Out of memory %d.\n", __LINE__);
          return -1;
        }
        for (size_t col = 0; col < columns_per_row[col]; col++) {
          if (scanf("%d", &c[row][col]) != 1) {
            fprintf(stderr, "Failure to read data.\n");
            return -1;
          }
        }
      }
    
      (void) m;  // m not used when debugging with commented out code
      // int r = shop(m, rows, columns_per_row, c);
      // printf ("%d\n", r);
      return 0;
    }