Jack
Jack

Reputation: 16724

what does the - operator do with char *?

I new to C. I am reading a find-replace algorithm for C and I am a bit confused what the - & + operators do in this code:

char *replace(char * src, const char * search, const char * replace) {
   char * buffer = malloc(4096);  //allocate 4096 bytes in memory to new string
   char * p; //substring of my search in the src string
   int i;

   p = strstr(src, search);
   if ( NULL == p ) return src; if // 'search' not found on 'src' return src
      i =  p - src; //index of my substring

   strncpy(buffer, src, i); //copy the substring value to buffer
   sprintf(buffer + i, "%s%s", replace, 
   p + strlen(search)); // ???

   return buffer;
}

Upvotes: 0

Views: 201

Answers (4)

paxdiablo
paxdiablo

Reputation: 882028

Since p is a location in your character array (string) and src is the start of it,

i = p - src;

will set i to the index at which p points.

For example, consider the following memory layout:

 [0] [1] [2] [3] [4] [5] [6] [7] [8]  [9]  <-- Indexes
 123 124 125 126 127 128 129 130 131  132  <-- Addresses
+---+---+---+---+---+---+---+---+---+----+
| H | i | , |   | w | o | r | l | d | \0 |
+---+---+---+---+---+---+---+---+---+----+
  ^               ^
  |               |
 src              p

In this case, p - src will give you 127 - 123 or 4, which is the index of the w within "Hi, world".

This is called pointer arithmetic is covered in Additive operators in the ISO standard (C99 6.5.6/9):

When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object; the result is the difference of the subscripts of the two array elements.

It provides a scaled way of working out differences within the same array or with one pointing just beyond the end of the array (all else is undefined).

By that I mean doing pointer arithmetic with (for example) four-byte integers, will give you a difference of one between the addresses of arr[7] and arr[8], not four as some may think.

The buffer + i construct is simply another way of saying &(buffer[i]), the address of the ith element of the array buffer. I actually prefer the latter method since it seems more explicit in what I'm trying to represent.

For what it's worth, that's not actually a very good string replacement code. It has numerous problems:

  • if no replacements are made, you have a 4K memory leak with buffer.
  • in any case, you should always check to ensure malloc hasn't failed.
  • you have a possibility of buffer overflow the way the new string is allocated, you should really allocate based on the lengths of src search and replace.
  • you could create the new string with a single sprintf ("%*.*s%s%s", i, i, src, replace, &(src[i + strlen (search)])); or a strcpy and two strcat operations. Mixing the two seems incongruous to me.

Upvotes: 5

Elalfer
Elalfer

Reputation: 5338

Read more on pointer arithmetic.

Basically + for char *:

a=a+1  =>  a=(char *) ( (int)a + sizeof(char) )

Upvotes: 0

Steve
Steve

Reputation: 31652

p is just a pointer - an integer value.

The + and - operators work exactly as you'd expect - they increment or decrement the value of the pointer.

If you think of strings as a contiguous array of chars, you're just talking about a location within that string.

Upvotes: 1

amit
amit

Reputation: 178491

it is a simple pointer arithmetics.

buffer + i is the substring of buffer, that starts from the ith character [until the end]

p - src is giving you the offset between p to src.

Upvotes: 1

Related Questions