2016-10-04 3 views
-3

Я пытаюсь назначить элемент из указателя того же значения, что и другой элемент из того же указателя.Назначение элемента указателя на другой элемент из того же указателя

int testFunc() { 
    char *p = "123"; 
    p[0] = p[2]; 
    return 0; 
} 

Любопытно, почему приведенный выше код не работает - и какой лучший способ достичь того, что я пытаюсь сделать?

+0

Вы вряд ли хотите, чтобы «присвоить элемент от указателя то же значение, что и другой элемент от того же указателя ", но из объектов, которые они ** указывают на **! Также вы хотите прочитать [ask] и предоставить [mcve]. – Olaf

+0

Этот код пытается изменить строковый литерал (который является неопределенным поведением) в строке, к которой ничего не имеет доступа к функции; что именно вы пытаетесь достичь? –

+0

@Olaf В этом вопросе нет ничего плохого в том, что касается политики SO. Введенный код содержит MCVE. Единственная проблема здесь заключается в отсутствии исследований, прежде чем задавать FAQ. – Lundin

ответ

4

У вас возникла проблема, поскольку вы пытаетесь изменить string literal, который вызывает undefined behavior.

Проблема заключается в

p[0] = p[2]; 

в то время как p указывает на строкового литерала.

кавычки C11, глава §6.4.5, Строковые литералы

[...] Если программа пытается изменить такой массив, поведение не определено.

Вы должны иметь массив вместо этого, т иметь возможность изменять содержимое, что-то вроде

char parr[] = "123"; 

, а затем

parr[0] = parr[2]; 

будет делать.

1

Когда вы пишете char *p = "123", p указывает на первый элемент 4 символов только для чтения памяти. Действительно, вы должны написать const char* p = "123", чтобы вызвать сбой компиляции в заявлении p[0] = p[2];.

Если вы хотите изменить строку, используйте автоматическую продолжительность хранения; т.е. написать

char[] p = "123";

p является тогда char[4] типа, с NUL-терминатор для конечного элемента.

+0

Стандарт не требует, чтобы память была только для чтения. Он просто говорит, что он не должен быть изменен программистом. Но тогда он позволяет реализациям предоставлять модифицируемую память. – Olaf

0

char * p = "123";

При определении указателя, как это будет сохранять данные в только для чтения сегмента памяти, что является причиной, вы не можете изменить данные