Что произойдет, если я увеличим переменную массива?

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

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

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

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


person Pilpel    schedule 07.09.2011    source источник
comment
Этот указатель не находится в стеке.   -  person Daniel A. White    schedule 07.09.2011
comment
В изменении указателя на динамически выделенную память нет ничего изначально неправильного: char * p = new char[100]; ++p; Дело в том, что вы должны вызывать delete с исходным указателем, например delete p-1; Это кошмар обслуживания, но не недопустимый по своей сути.   -  person Kerrek SB    schedule 07.09.2011


Ответы (5)


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

EDIT:
комментарии заставили меня осознать ваши истинные намерения: что-то вроде:

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

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

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

person amit    schedule 07.09.2011
comment
Хорошо, а как насчет просто char*? - person Pilpel; 07.09.2011
comment
Это касается примера кода, но не отвечает на вопрос. Спрашивающий даже признал, что образец кода вызывает сомнения. - person Binary Worrier; 07.09.2011
comment
@Pilpel: я отредактировал свой ответ, сначала не понял тебя правильно. - person amit; 07.09.2011
comment
@amit Но даже если мы объявим char *a = hai или char a[]=hai, когда мы делаем a++; мы потеряем начальный адрес в обоих случаях, верно? насколько они разные? - person Sorcrer; 09.03.2017

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

Вы можете сделать что-то вроде этого:

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

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

person John Bode    schedule 07.09.2011

Линия:

char arr[] = "one two three";

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

arr++;

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

char* ptr = arr;
ptr++;

чтобы добраться до второго символа массива arr.

person John Humphreys    schedule 07.09.2011

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

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

person Binary Worrier    schedule 07.09.2011

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

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-го индексированного элемента в массиве, используя адрес массива.

person Venkatakrishna Kalepalli    schedule 24.04.2015