Я думаю, что самое близкое, что вы можете сделать, это инициализировать простой char[]
(не символ * []) с литералом:
char foo[] = "foo";
Это все равно будет выполнять копирование в какой-то момент.
Единственный способ обойти это - использовать вызовы системного уровня, чтобы пометить страницу, на которой находится строковый литерал, как доступную для записи. В этот момент вы на самом деле говорите не о C или C ++, а о Windows (или любой другой системе, на которой вы работаете). Вероятно, это возможно в большинстве систем (если только данные не находятся в ПЗУ, как, например, во встроенной системе), но я точно не знаю деталей.
Да, и не забывайте, что в вашем примере:
char* foo[] = {
"foo",
"foo"
};
Поскольку в стандарте (C99 6.4.5 / 6 «Строковые литералы») говорится:
Не определено, различаются ли эти массивы при условии, что их элементы имеют соответствующие значения.
Нет уверенности в том, будут ли 2 указателя в этом массиве указывать на одни и те же или отдельные объекты. Почти во всех компиляторах эти указатели будут указывать на один и тот же объект по одному и тому же адресу, но это не обязательно, и в некоторых более сложных ситуациях указателей на строковые литералы компилятор может выдать 2 отдельные идентичные строки.
Вы могли бы даже иметь сценарий, где один строковый литерал существует «внутри» другого:
char* p1 = "some string";
char* p2 = "string";
p2
вполне может указывать на конец строки, на который указывает p1
.
Таким образом, если вы начнете изменять строковые литералы с помощью какого-либо хака, который вы можете выполнить в системе, вы можете непреднамеренно изменить некоторые «другие» строки. Это одна из вещей, которую может привести неопределенное поведение.