Ответ 1
Первый создает массив char, содержащий строку. Содержимое массива можно изменить. Второй создает указатель на символ, который указывает на строковый литерал. Строковые литералы не могут быть изменены.
Я ожидаю, что оба следующих вектора имеют одинаковое представление в ОЗУ:
char a_var[] = "XXX\x00";
char *p_var = "XXX";
Но странно, вызов функции библиотеки типа f(char argument[])
разбивает запущенное приложение, если я его вызываю, используя f(p_var)
. Но использование f(a_var)
- это Ok!
Почему?
Первый создает массив char, содержащий строку. Содержимое массива можно изменить. Второй создает указатель на символ, который указывает на строковый литерал. Строковые литералы не могут быть изменены.
При угадывании функция f
изменяет содержимое переданной ему строки.
Как говорили другие, char *p_var = "XXX";
создает указатель на строковый литерал, который не может быть изменен, поэтому реализации компилятора могут повторно использовать литералы, например:
char *p_var = "XXX";
char *other = "XXX";
Компилятор может выбрать оптимизацию, сохраняя "XXX" только один раз в памяти и указывая на это оба указателя, изменение их значения может привести к неожиданному поведению, поэтому вы не должны пытаться изменить их содержимое.
Массивы можно рассматривать (как правило) как указатели, но это не означает, что они всегда взаимозаменяемы. Как сказал другой, ваш p_var указывает на литерал, что-то статическое, которое нельзя изменить. Он может указывать на что-то еще (например, p_var = & a_var [0]), но вы не можете изменить исходное значение, указанное вами кавычками....
Аналогичная проблема заключается в том, что вы определяете переменную как массив в одном файле, а затем extern - используете ее как указатель.
Привет