У вас есть двумерный массив указателей.
char * array[5][5];
^^^^^^
Таким образом, эти утверждения
array[0][0] = "AAA";//Again I can change its value
array[1][0] = "BBB";//And again.
не изменили изначально заостренные строки. Они изменили указатели, которые являются их ценностями. Теперь указатель array[0][0]
указывает на литерал "AAA"
, а указатель array[1][0]
указывает на литерал "BBB"
.
В этом утверждении
array[0][0] = strdup(array[1][0]);
вы опять не изменились строковый литерал, на который указывает указатель array[0][0]
. Вы изменили значение самого указателя. После этого оператора указатель array[0][0]
указывает на выделенную динамическую память, возвращаемую функцией strdup
, а динамически размещенный массив содержит копию строкового литерала, на который указывает указатель array[1][0]
. Это то, что делает функция strdup
.
Этот оператор
strcpy(array[0][0], array[1][0]);
является избыточным, поскольку динамически размещенный массив, на который указывает указатель array[0][0]
, уже хранит копию строкового литерала. на который указывает указатель array[1][0]
.
Обратите внимание на то, что, например, такое объявление
const char *p = "AAA";
означает, что вы не можете изменить указанный объект, являющийся строковым литералом "AAA ». Но вы можете изменить значение самого указателя, например,
p = "BBB";
Этот оператор не изменил строковый литерал "AAA"
. Он изменил значение указателя p
, который теперь указывает на строковый литерал "BBB"
.
Если вы хотите, чтобы указатель также был неизменяемым, вы должны объявить его как
const char * const p = "AAA";
В этом случае такой оператор
p = "BBB";
вызовет ошибку компилятора.