Что произойдет, если я увеличу переменную массива? - PullRequest
2 голосов
/ 07 сентября 2011

Я знаю, что изменять адрес указателя, если он лежит в куче, небезопасно, потому что последующее его освобождение может вызвать некоторые проблемы, но безопасно ли это делать, если указатель объявлен в стеке?

Я говорю о чем-то вроде этого:

char arr[] = "one two three";
arr++;
//or arr--;

Надеюсь, я понял это правильно, обратившись к массиву символов в качестве указателя.

Ответы [ 5 ]

4 голосов
/ 07 сентября 2011

вы не можете изменить адрес массива.Это даст ошибку времени компиляции.посмотрите: http://codepad.org/skBHMxU0

РЕДАКТИРОВАТЬ:
комментарии заставили меня понять ваше истинное намерение: что-то вроде:

char *ptr = "one two three";
ptr++;

Нет проблем сЭто.строка «один два три» является константой, и вы можете свободно изменять ptr, но учтите, что у вас могут возникнуть проблемы с поиском начала этой строки снова ... [но утечка памяти не произойдет]

Как правило, вы несете ответственность за память, специально выделенную для нее с помощью malloc / new, а за остальное отвечает компилятор.

3 голосов
/ 07 сентября 2011

Как написано, ваш код не будет работать, потому что операнд ++ должен быть изменяемым lvalue, а выражения массива не являются изменяемыми lvalue.

То, что вы можете сделать, выглядит примерно так:

char arr[] = "one two three";
char *ptr = arr;  // ptr points to the leading 'o'
...
ptr++; // ptr now points to 'n'

Что касается безопасности, вы все равно можете столкнуться с проблемами, если результат увеличения или уменьшения ptr заставляет его указывать на память вне массива, которая может быть или не быть безопасной для доступа или изменения.

2 голосов
/ 07 сентября 2011

Строка:

char arr[] = "one two three";

создает массив (что означает, что его местоположение ИСПРАВЛЕНО), это не то же самое, что указатель, поскольку местоположение указателей можно перемещать.Массив инициализируется по умолчанию с содержимым «один два три»;Вы можете изменить содержимое массива как log, так как он не увеличивается в размере, но вы не можете переместить arr.

arr++;

, таким образом, будет ошибкой.Однако вы можете сделать:

char* ptr = arr;
ptr++;

, чтобы получить второй символ массива arr.

0 голосов
/ 24 апреля 2015

Вы не можете увеличить переменную массива / имя массива, однако вы можете получить доступ к любому элементу массива, используя имя массива / переменную массива. Это причина, почему указатели пришли к картине. Адреса массивов неизменяемы Например,

int k[3]={1,4,3};
printf("%d", *(k+1));  // compiles without any warning o/p is 4
printf("%d", *k++); //Will throw an error, Trying to modify an unmodifiable value

здесь, во фрагменте выше, строка 2: мы не увеличиваем переменную массива, однако мы выбираем значение 1-го индексированного элемента в массиве, используя адрес массива

0 голосов
/ 07 сентября 2011

Дело не в том, где живет указатель (куча или стек), а в том, где находится память, на которую указывает указатель.

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

...