**(matr1+(i*width)+j)
не имеет смысла.
alloc2Df(height, width)
возвращает динамический массив m
размера height
.Каждый элемент m[i]
является указателем на первый элемент массива float
размером width
.(Особое внимание: все m[i]
указывают на разные куски одного и того же большого float
массива, но это не имеет значения для доступа к элементу.)
Вот диаграмма, показывающая matr1 = alloc2Df(3, 4)
:
matr1
|
v
[ ]----------------------->[0.0]
[ ]-------- [0.0]
[ ]-- \ [0.0]
\ \ [0.0]
\ ------------->[0.0]
\ [0.0]
\ [0.0]
\ [0.0]
---------------->[0.0]
[0.0]
[0.0]
[0.0]
Пока i
равно 0
(первая итерация внешнего цикла), мы просто получаем доступ к **(matr1 + j)
(где j
идет от 0
до 2
):
matr1 --------v
matr1 + 0 -->[ ]----------------------->[1.0] X
matr1 + 1 -->[ ]-------- [0.0]
matr1 + 2 -->[ ]-- \ [0.0]
\ \ [0.0]
\ ------------->[1.0] X
\ [0.0]
\ [0.0]
\ [0.0]
---------------->[1.0] X
[0.0]
[0.0]
[0.0]
matr1 + j
приводит к указателю на один из элементов в первом массиве (показан слева выше).Разыменование его с помощью *
дает нам сам элемент массива, который является другим указателем;разыменование, которое (снова с *
) отправляет нас к одному из float
s справа (помечено X
).
Пока все в порядке.
Однаково второй итерации внешнего цикла i
равно 1
.Поэтому указатели, которые мы вычисляем по matr1 + i*width + j
, являются matr1 + 4 + 0
, matr1 + 4 + 1
, matr1 + 4 + 2
(потому что width = 4
, height = 3
в этом примере).
matr1 --------v
matr1 + 0 -->[ ]----------------------->[1.0]
matr1 + 1 -->[ ]-------- [0.0]
matr1 + 2 -->[ ]-- \ [0.0]
\ \ [0.0]
matr1 + 4 --> ? \ ------------->[1.0]
matr1 + 5 --> ? \ [0.0]
matr1 + 6 --> ? \ [0.0]
\ [0.0]
---------------->[1.0]
[0.0]
[0.0]
[0.0]
Две вещи выделяются:
matr1 + 3
никогда не вычисляется.Это, вероятно, ошибка в логике.(Если бы в нашем примере было height > width
, это оставило бы «отрицательный пробел»; т. Е. Вместо пропуска элементов, он получал бы доступ к одним и тем же элементам дважды.) matr1 + 4
указывает после конца массиваналево.Фактически, все указатели matr1 + i*width + j
указывают, кто знает, где, если i > 0
.Я не удивлен, что взятие недопустимого указателя, разыменование его (*
), затем взятие любого значения, найденного в памяти, как другого указателя и разыменование этого снова (*
), вызывает сбой.
Существует простое исправление:
matr1[j][i]
Или, если вы хотите использовать *
вручную:
*(*(matr1 + j) + i)
Нет необходимости умножать что-либо.Вы не пытаетесь эмулировать доступ к двумерному массиву при наличии большого одномерного массива;у вас уже есть двухуровневая структура, в которой первый уровень содержит правильные предварительно вычисленные смещения в массиве второго уровня.
matr1[j]
(или *(matr1 + j)
) - указатель на правый блок во второммассив.Применение [i]
(или *(... + i)
) к этому дает вам правильный элемент в чанке.