c - Array resizing and realloc function -


now try improve knowledge of pointers reading "understanding , using c pointers" richard reese.

here's 1 code example book concerning realloc() function.

char* getline(void) {     const size_t sizeincrement = 10;     char* buffer = malloc(sizeincrement);     char* currentposition = buffer;     size_t maximumlength = sizeincrement;     size_t length = 0;     int character;      if(currentposition == null) { return null; }      while(1) {         character = fgetc(stdin);          if(character == '\n') { break; }          if(++length >= maximumlength) {             char *newbuffer = realloc(buffer, maximumlength += sizeincrement);              if(newbuffer == null) {                 free(buffer);                 return null;             }              currentposition = newbuffer + (currentposition - buffer);             buffer = newbuffer;         }          *currentposition++ = character;     }      *currentposition = '\0';     return buffer; } 

the main idea read symbols buffer until meet \n.

we don't know total number of symbols read it's reasonable use realloc() function expand buffer periodically.

so, expand buffer use:

char *newbuffer = realloc(buffer, maximumlength += sizeincrement); 

in case realloc() returns newbuffer pointer expanded buffer.

after that, if realloc() invoked successfully, currentposition recalculated as:

currentposition = newbuffer + (currentposition - buffer); 

question:

is valid recalculate currentposition in such way?

as know, after realloc() invocation buffer pointer invalidated. (see, example, this). access buffer pointer leads undefined behaviour. so... wrong?

this code causes undefined behaviour:

currentposition = newbuffer + (currentposition - buffer); 

after passing pointer realloc, pointer variable (and other pointers based on pointer) become indeterminate, same status uninitialized variable has.

reference: c11 6.2.4/2:

[...] value of pointer becomes indeterminate when object points (or past) reaches end of lifetime.

then, doing pointer arithmetic on invalid pointer causes undefined behaviour, c11 6.5.6/8:

when expression has integer type added or subtracted pointer, [...] if both pointer operand , result point elements of same array object, or 1 past last element of array object, evaluation shall not produce overflow; otherwise, behavior undefined

the pointer operand doesn't point object @ time. object used point has been freed.

in fact, evaluating pointer @ may cause undefined behaviour, since indeterminate value may trap representation. (imagine system loading value address register performs hardware check address belongs process). refs: c11 3.19.2, 6.2.6.1/5:

if stored value of object has such representation , read lvalue expression not have character type, behavior undefined


the correct way write code have been:

if(++length >= maximumlength) {     size_t currentoffset = currentposition - buffer;      char *newbuffer = realloc(......     // ...      currentposition = newbuffer + currentoffset;     buffer = newbuffer; } 

(personally use offset whole way , instead of currentposition, avoid problem entirely)


Comments

Popular posts from this blog

authentication - Mongodb revoke acccess to connect test database -

r - Update two sets of radiobuttons reactively - shiny -

ios - Realm over CoreData should I use NSFetchedResultController or a Dictionary? -