Я работал над небольшим проектом, который имеет дело с матричными вычислениями на C.
Я проводил некоторые тесты на код, который я написал, и столкнулся с каким-то невероятно запутанным поведением.
Прежде чем я задам этот вопрос, вот некоторые соответствующие коды.
Определение матрицы:
typedef struct
{
double **matrix;
int rows;
int cols;
int dimensions[2];
char *str_dims;
} Matrix;
Когда я инициализирую матрицуЯ выделяю память, используя malloc для количества строк, затем перебираю строки, выделяя память для всех столбцов, используя calloc, чтобы они были инициализированы 0.
void init_matrix(Matrix *x, int i, int j)
{
x->matrix = malloc(x->rows * sizeof(double *));
for (int i = 0; i < x->rows; i++)
x->matrix[i] = calloc(x->cols, sizeof(double));
}
У меня также есть функциональность генерации случайной матрицы,
Matrix get_rand_matrix(int i, int j)
{
Matrix x;
init_matrix(&x, i, j);
srand(time(NULL));
for(int i = 0; i < x.rows; i++)
for(int j = 0; j < x.cols; j++)
x.matrix[i][j] = rand();
return x;
}
Непонятное поведение
Помимо того, что код, скорее всего, был довольно ужасным по стандартам древних, я думал, что он работает правильно. Однако, к счастью, когда я проводил некоторое тестирование (печать матрицы), я бездумно увеличил цикл, отвечающий за итерации по столбцам матрицы, на 1, и это был результат, который я получил. (Отформатирован для вашего удовольствия от просмотра.)
+-------------+--------------+-----+
|739979002.00 | 1854570721.00| 0.00|
|130427701.00 | 402893063.00 | 0.00|
|1973118592.00| 135400441.00 | 0.00|
|1707001127.00| 1093842609.00| 0.00|
+----------------------------------+
Там, где ожидаемый результат был бы,
+-------------+--------------+
|739979002.00 | 1854570721.00|
|130427701.00 | 402893063.00 |
|1973118592.00| 135400441.00 |
|1707001127.00| 1093842609.00|
+----------------------------+
Код, который сгенерировал это только для того, чтобы держать вас в темноте,
Matrix m = get_rand_matrix(4, 2);
for(int i = 0; i < m.rows; i++)
{
for(int j = 0; j < m.cols + 1; j++)
printf("%.2lf ", m.matrix[i][j]);
printf("\n");
}
Вопрос
Честно говоря, я понятия не имею, почему я не получаю segfault и у меня нет доступа к элементам с нулевой инициализацией за пределами (что я бы подумалбыть) границы памяти, которая была выделена. Я могу только предположить, что это ошибка с моей стороны, объединив malloc
и calloc
вместе, но опять же, я также не понимаю, почему это не сработает.
Кто-нибудь знает, что происходитпочему 0 инициализированных двойников за пределами выделенной памяти? Я довольно новичок в C и распределении памяти в целом, и это меня совершенно поразило.
Интересное дополнение
Некоторые элементы повторяются при увеличении столбцаусловие выхода из цикла (генерируется с помощью j < m.cols + 5
)
+-------------------------------------------------------------------------------+
|549092153.00 | 1317836633.00 | 0.00| 0.00 | 218607745.00 |1326282480.00 | 0.00 |
|218607745.00 | 1326282480.00 | 0.00| 0.00 | 715372192.00 |976468777.00 | 0.00 |
|715372192.00 | 976468777.00 | 0.00| 0.00 | 103851159.00 |363785358.00 | 0.00 |
|103851159.00 | 363785358.00 | 0.00| 0.00 | 0.00 | 0.00 | 0.00 |
+-------------------------------------------------------------------------------+
Я увеличил приращение до +1000, и он все еще продолжает печатать 0,00 и повторяющиеся числа.