Причина, по которой вы получаете вывод, состоит в том, что ваш *(*(ptr+i)+j) = sh
устанавливает все значения char *
(кроме первого, который вы обработали специально) на одно и то же значение, которое является адресоммассив данных в sh
.Существует только одна копия sh
, одна копия данных массива;все ваши char *
ы указывают на эту единственную копию.Когда вы распечатываете значения позже, вы просто печатаете одну и ту же копию данных снова и снова через разные указатели на нее - так что вы получаете все, что вы положили в sh
в последний раз, когда вы изменяли его, а не то, что былов нем, когда вы устанавливаете указатель.
Вы, вероятно, ожидали, что каждый char *
получит новую копию массива вместо того, чтобы просто указывать на sh
, но если это то, что вы хотите, вы должны скопироватьданные сами.
Итак ... если вы замените эту строку:
*(*(ptr+i)+j)=sh;
на что-то вроде:
*(*(ptr+i)+j)=malloc(sizeof(sh));
strcpy( *(*(ptr+i)+j), sh );
или
ptr[i][j] = calloc(1,sizeof(sh));
strcpy( ptr[i][j], sh );
вы получите то, что ожидали, потому что каждый char *
будет указывать на новую копию строки, которая была в sh
на момент копирования.Вы должны будете помнить, чтобы освободить их позже, вместе со всем остальным, что вы malloc()
редактировали, хотя.
Большинство ваших malloc()
строк также неверны, но с char *
, char **
и char ***
, вероятно, имеют одинаковый размер в вашей системе, все равно работает.
ptr=(char *)malloc(row*sizeof(char *));
должно быть
ptr = (char ***)malloc(row*sizeof(char **));
, поскольку вы выделяете массив char **
(указатель на указатель на char
), доступ к которому осуществляется через char ***
(указатель на указатель на указатель на char
).Аналогично:
*(ptr+i)=(char *)malloc(rw*sizeof(char *));
должно быть
*(ptr+i)=(char **)malloc(rw*sizeof(char *));
или
ptr[i] = (char **)malloc(rw * sizeof(char *));
для выделения массива char *
(указатель на char
), доступ к которому осуществляется черезchar **
(указатель на указатель на char
).
Преобразования перед вашими malloc()
вызовами на самом деле являются необязательными - результат malloc()
void *
будет преобразован в любой тип указателя, который вы ему присвоили.Однако в этом случае наличие приведений должно было заставить ваш компилятор предупредить вас, что вы ошиблись в типах.