首页 > 解决方案 > Realloc 无法使用更大的数组

问题描述

我有一个程序可以从输入中加载矩阵和数学运算,然后计算结果。在大多数情况下,一切都运行顺利,除了更大的矩阵。格式是:行数,列数,然后是单独的行。
10 4
8 5 -6 -3
-7 4 7 2
2 8 -5 -9
-8 2 4 8
-3 8 10 9
-4 -2 7 -3
4 3 -2 3
-3 10 -8 0
8 -7 -2 -5
0 2 7 -6
*
4 10
-5 2 8 0 4 7 -3 -2 0 -2
-1 8 10 -7 1 3 -6 -4 -7 6
-5 5 -7 -1 7 - 7 -3 1 -4 2
5 -10 4 -1 -1 6 -2 -7 -4 7
+
10 10
-4 6 -10 0 -4 -7 2 8 -8 10
-1 -5 -4 1 8 - 1 0 8 -4 9
-2 -4 10 10 5 -5 6 -6 7 -9
5 8 -10 2 9 2 9 -4 3 0
1 9 4 5 -9 9 7 -4 0 6
-8 7 9 -4 -3 5 4 4 -9 10
-9 -10 5 -8 -7 5 -7 -8 5 -9
4 7 6 6 -9 2 -2 4 5 9
6 2 0 -1 -10 0 10 4 8 -3
4 4 -8 -5 4 3 -3 -10 4 -7
+
10 3
5 - 7 0
-2 -6 -6
9 -2 7
9 -2 -5
-1 -1 7
-9 -5 -6
-3 0 5
-3 1 7
-5 3 5
-9 5 -5
*
3 10
-10 -6 -5 -4 10 6 9 1 4 -7
-6 5 -1 -8 -5 8 10 -5 0 1
8 8 -2 4 -6 6 -4 -9 -2 7
+
10 10
6 -4 - 9 8 8 -8 -4 7 0 5
-8 -2 -6 1 5 -10 -3 -2 4 -10
2 -9 3 -1 -9 8 3 -8 2 8
1 -1 -2 10 -8 3 2 -8 -5 4
-7 4 -4 10 -10 3 5 6 -7 -10
-9 0 -6 8 7 -6 7 5 3 3
-9 -8 -10 6 -10 -1 -3 2 3 9
-6 -4 -8 -5 4 -4 -9 -6 9 5
-2 -6 -5 -3 3 -10 7 -8 -5 -9
9 5 2 4 -3 3 5 10 -7 5

此输入应生成一个 10x10 矩阵,但在加载第三个矩阵之前,由于第 106 行上的重新分配,我得到了一个 NULL 指针。我无法分配足够的空间来存储第三个矩阵的值。我检查了原始指针和想要的大小,两者都不是零 - 需要分配的大小是 200 * 4 字节(整数)。由于我不知道问题出在哪里,所以我在下面发布了整个代码。如果有人能发现问题,我将不胜感激。

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

int load_matrix (int n, int m, int *address, char letter, int *mat, int n_matrix) {
  /*Loads a matrix with the given dimensions, stores its values and its dimensions in separate arrays.*/
  int aux, control, count = n * m, start = 0;
  for (int i = 0; i < n_matrix; i++) {
    start += (mat[i * 3 + 1] * mat[i * 3 + 2]);  /*Finds the index where to start storing.*/
  }
  for (int i = 0; i < (n * m); i++){
      control = scanf("%d", &aux);  /*Scans a value.*/
      if (control != 1) return -1;  /*Not an integer.*/
      address[start + i] = aux;  /*Stores the value.*/
      count--;
    }

  if (count != 0) return -1;  /*Not enough values.*/
  mat[n_matrix * 3 + 1] = n;
  mat[n_matrix * 3 + 2] = m; /*Stores the dimensions and letter (unnecessary).*/
  mat[n_matrix * 3] = letter;
  return 0;
}

int multiply(int *values, int amount_values, int *matrices, int last_mat) {
  /*Multiplies the two last matrices in the array, deletes those two and stores the new one instead, returns the new amount of values.*/
  int c = matrices[last_mat * 3 + 2], r =  matrices[(last_mat - 1) * 3 + 1];
  int a = matrices[(last_mat - 1) * 3 + 2];
  int new_size = r * c, aux;  /*Stores the dimensions, indeces...*/
  int start_right = amount_values - (matrices[last_mat * 3 + 1] * matrices[last_mat * 3 + 2]);
  int start_left = start_right - (matrices[(last_mat - 1) * 3 + 1] * matrices[(last_mat - 1) * 3 + 2]);
  int *result = calloc(new_size, sizeof(int));
  for (int i = 0; i < r; i++) {
    for (int j = 0; j < c; j++) {  /*Iterates over every position in the result matrix.*/
      aux = 0;
      for (int k = 0; k < a; k++) {  /*Iterates over the right row and left column.*/
        aux += (values[start_left + i * a + k] * values[start_right + k * c + j]);
      }
      result[i * c + j] = aux;  /*Stores the resulting value.*/
    }
  }
  if (start_left + new_size > amount_values) {
    int *temp = realloc(values, (start_left + new_size) * sizeof(int));
    if (temp != NULL) values = temp;
    else {
      free(values);
      free(matrices);
      free(result);
      return -1;
    }
  }
  matrices[(last_mat - 1)* 3 + 1] = r;
  matrices[(last_mat - 1)* 3 + 2] = c;
  for (int i = 0; i < new_size; i++) values[i + start_left] = result[i];  /*Copies values from the result to the original array.*/
  free(result);
  return new_size + start_left;
}

void negate(int *values, int amount_values, int *matrices, int last_mat) {
  /*Negates the last matrix in the array.*/
  int size = matrices[last_mat * 3 + 1] * matrices[last_mat * 3 + 2];
  for (int i = 1; i < size + 1; i++) values[amount_values - i] *= -1;
}

int sum(int *values, int *matrices, int last_mat, int *result) {
  /*Adds up allthe matrices in the array, returns the size of the resulting array.*/
  int r = matrices[1], c = matrices[2];
  for (int i = 0; i < last_mat; i++) {
    if (r != matrices[i * 3 + 1] || c != matrices[i * 3 + 2]) return -1;  /*Some dimensions are not correct.*/
    for (int j = 0; j < r * c; j++) result[j] += values[i * r * c + j];
  }
  return r * c;
}

/* The main program */
int main(int argc, char *argv[]) {
  int mat_count = 0, aux, n, m, *values, *temp, size = 0, letter = 65, *arr_matrices;
  char operation = 0, newlline;
  arr_matrices = calloc(2 * 3, sizeof(int));
  values = calloc(13, sizeof(int));
  while ((aux = scanf("%d", &n)) != EOF) {
    if (aux != 1) {
      free(temp);
      free(values);
      free(arr_matrices);
      fprintf(stderr, "Error: Chybny vstup!\n");
      return 100;
    }
    aux = scanf("%d", &m);
    if (aux != 1) {  /*One of the dimensions is not an int.*/
      free(temp);
      free(values);
      free(arr_matrices);
      fprintf(stderr, "Error: Chybny vstup!\n");
      return 100;
    }
    if (mat_count > 1) {  /*If there is 2+ matrices, resizes the array of dimensions.*/
      temp = realloc(arr_matrices, (mat_count + 1) * 3 * sizeof(int));
      if (temp != NULL) arr_matrices = temp;
      else {
        free(values);
        free(arr_matrices);
        return 101;
      }
    }
    size += (n * m);  /*Increases the size of value array and resizes it.*/
    temp = realloc(values, (size + 1) * sizeof(int));  //this is problematic
    if (temp != NULL) values = temp;
    else {
      free(values);
      free(arr_matrices);
      fprintf(stderr, "Can't realloc.\n");
      return 101;
    }
    aux = load_matrix(n, m, values, letter, arr_matrices, mat_count);
    if (aux == -1) {  /*Some of the values were not ints or there were not enough of them.*/
      free(values);
      free(arr_matrices);
      fprintf(stderr, "Error: Chybny vstup!\n");
      return 100;
    }
    scanf("%c", &newlline);
    if (mat_count > 0) {
      if (operation == 42) {  /*If needs to multiply, checks the dimensions adn performs.*/
        if (arr_matrices[(mat_count - 1) * 3 + 2] != n) {
          free(values);
          free(arr_matrices);
          fprintf(stderr, "Error: Chybny vstup!\n");
          return 100;
        }
        size = multiply(values, size, arr_matrices, mat_count);
        if (size == -1) {
          fprintf(stderr, "Can't realloc.\n");
          return 101;
        }
        mat_count--;
      }
      if (operation == 45) negate(values, size, arr_matrices, mat_count);
    }
    aux = scanf("%c", &operation);
    if (aux == EOF) break;
    scanf("%c", &newlline);
    mat_count++;
    letter++;
  }
  mat_count++;
  int *result = calloc(arr_matrices[1] * arr_matrices[2], sizeof(int)), res_len;
  res_len = sum(values, arr_matrices, mat_count, result);  /*Allocs an array for result and stores there.*/
  free(values);
  if (res_len == -1) {
    free(arr_matrices);
    fprintf(stderr, "Error: Chybny vstup!\n");
    free(result);
    return 100;
  }
  fprintf(stdout, "%d %d\n", arr_matrices[1], arr_matrices[2]);  /*Prints the dimensions and values of the resulting matrix.*/
  for (int i = 0; i < res_len; i++) {
    if ((i + 1) % arr_matrices[ 2] == 0) fprintf(stdout, "%d\n", result[i]);
    else fprintf(stdout, "%d ", result[i]);
  }
  free(arr_matrices);
  free(result);
  return 0;
}

标签: crealloc

解决方案


推荐阅读