Источник вашей путаницы:
Тип
int m1[2][2]; // a *single* block of memory of size 2*2*sizeof(int)
//
// this is a *real* 2d-array
равен , а не такой же, как у
int **m2; // a pointer of size sizeof(int*) almost certainly the
// equal to sizeof(void*)
//
// This could be made to point at at least two logically
// distinct blocks of memory and *act* like a 2d-array
Да, m2
(указатель на указатель) можно разыменовать , используя [][]
, но m1
(фактический двумерный массив) не может быть разыменованным с **
.
Это означает, что ваш вызов поменять строки - ужасная ошибка.Посмотрите, почему ...
matrix[0]
- это первый подмассив (и int[2]
, содержащий {1,2}
), его адрес является пустой операцией, которая получает адрес матрицы [0] [0], это место в памяти, содержащее целочисленное представление 1
(то есть это указатель на int). - Аналогичный аргумент применяется к
&matrix[1]
, оно указывает на памятьсодержащий 2
.
Вы вызываете swapRows
, который думает, что эти аргументы являются указателями на указатели на int (а это не так, поэтому ваш компилятор выдает предупреждение).Однако он будет работать, потому что указатель на int имеет тот же размер, что и указатель на указатель на int (это не гарантируется строго, но обычно вам это сходит с рук).Когда он запускается, он заменяет содержимое размером с точку-на-интервал a
на содержимое размера указателя на-int b
.Если случится так, что sizeof(int) == sizeof(int*)
(что не редкость), это будет равносильно замене matix[0][0]
на matrix[1][0]
.
Это не то, что вы хотели.
Что вы можете с этим поделать?
- Объявите
matrix
в качестве указателя на указатель и выделите память, как в рваном массиве, затем используйте существующий своп - Объявите
matrix
в качестве массива указателей и выделите память для строк, затем используйте существующий своп - Сохраните существующее объявление
matrix
и перезапишите своп для замены каждого значения. - Сохранитесуществующее объявление
matrix
, но также предоставьте массив указателей аксессора, используйте существующий своп на аксессоре и всегда используйте аксессор (единственное возможное преимущество этого по сравнению с первыми двумя опциями - то, что все находится в стеке). - Использование хака "строка как структура".
Структура "строка как структура"
Учтите это
typedef struct {
int r[2];
} row_t;
row_t m3[2];
m3
- это массив структур, каждая из которых является массивом int
s.Доступ - это немного сомнительно: m3[i].r[j]
, , но вы можете сделать
row_t temp = m3[n];
m3[n] = m3[m];
m3[m] = temp;
, чтобы поменять строки.