Особенности работы с указателями.

Forums:

Рассмотрим такой вот пример . Есть си код =

char* result;   /* The malloc()ed string to return = "ответ" нашей функции вызывающему её блоку */
  char* block;    /* Each chunk of the string  = очердной кусок читаемой строки */
  char* ok;       /* Used to check for input errors  = идентификатор ошибки , которая может возникнуть при чтении.*/
  unsigned size=100;  /* The current size of the entire string , размерность читаемого блока данных  (читать будем из стандартного потока ввода.) */
  unsigned n; 
/* далее рабочая часть -*/ 

block = result = (char*)malloc( size  );
ok = (char*)realloc( result, size += 50 );
result = ok;

так вот спрашивается - указывают ли после проведённых действий result и block на один и тот же участок памяти (пересекаются ли области памяти - в том смысле, что память *block может быть 2/3 памяти в составе *result )
или нет?

vedro-compota's picture

насколько я понимаю, *block теперь будет действительно являться частью *result в смысле "размещения в памяти" , а не только " по составу" , но есть одна особенность - realloc вроде как может , в случае нехватки места переразместить объект в другой области памяти , тогда сразу возникает ряд допоолнительных вопросов =

1) будет ли переразмещёна память для *block - или что вообще произойдёт сданными, хранящимися по этому адресу?

2) Если память новое место для *block не выделяется - сохраняются ли данные ?, ведь если result перемещается, то преждезанимаемая память , опять же, освобождается.

_____________
матфак вгу и остальная классика =)

do_it's picture

1) то что лежало в *block никуда не денется в смысле не обнулится, но после realloc это просто будут данные в куче, а если ты захочешь обратиться туда через *block а не через realloc()енный *ok то скорей всего вылетит Segmentation fault

2) .

чувак, ты ваще че хочешь сделать?

rm -rf /

Wishmaster's picture

Откуда вы берете эти листинги? И зачем?

mechanism

vedro-compota's picture

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

_____________
матфак вгу и остальная классика =)

vedro-compota's picture

кстати, что-то разобраться не могу пока с этой темой)

_____________
матфак вгу и остальная классика =)

Wishmaster's picture

Если это тебе не задали, то не извращайся изучай плюсы пользуй new и delete. А если тебе это интересно, то пиши не непонятные листинги из сети, а делай упражнения из умных книжек. Благо таких сейчас не мало.

mechanism

do_it , смотри - тут что-то вроде того спрашивается- сначала резалт и блок "смотрят" на одну и ту же область памяти, затем память для резалта расширяется, причём здесь возможны два варианта =
1) память , находящиеся по адресу резалт не перемещаются , тогда получается что память , выделенная для *блок является ничем иным как частью резалт.

2) если же *резалт будет переведён на новое место (кстати, получается , что тогда адрес меняется....или же не меняется(само значение указателя)....) , тогда в соответствии со спецификацией функции (выше была ссылка) преждезанимаемый блок памяти должен быть освобожден, но будет ли он освобождён, если на него "направлен" указатель block ? или блок будет перенеён вместе с резалтом - вот что волнует ТС

_________ _ _ ______
dthcbz фкн вгу and co

vedro-compota's picture

Илья Владимирович считает, что =

После первого malloc они указывают на один и тот же участок. Затем на этом участке был вызван realloc, что должно выделить новую память и переопределить указатель. Теперь в ok содержится часть (и в result) "старой памяти", т.к. realloc выполняет копирование, если есть необходимость, а старой памяти сделается free(). Т.е. block будет уже "битым" указателем.

realloc() changes the size of the memory block pointed to by ptr to size bytes. The contents will be unchanged to the minimum of the old and new sizes; newly allocated memory will be uninitialized. If ptr is NULL, then the call is equivalent to malloc(size), for all values of size; if size is equal to zero, and ptr is not NULL, then the call is equivalent to free(ptr). Unless ptr is NULL, it must have been returned by an earlier call to malloc(), calloc() or realloc(). If the area pointed to was moved, a free(ptr) is done.

а вот куда они будут ссылаться и будут ли пересекаться - случайность для каждого конкретного случая

_____________
матфак вгу и остальная классика =)

vedro-compota's picture

то есть получается ,что указатель block может как быть "битым" так и не быть таковым- ведь в случае если realloc не выполняет переноса блока данных на новое место, то *block будет по-прежнему совпадать с *result , только теперь составлять 2/3 от последнего ?

ответ =

В теории так. Realloc выделяет новый кусок памяти, если есть в этом необходимость, но надо явно это проверить для каждой реализации (Windows, Linux, BSD), т.к. они могут отличаться.

_____________
матфак вгу и остальная классика =)