Increment char pointer
Asked Answered
B

7

7

The following code gives a seg fault at second line:

 char *tester = "hello";
 char a = (*tester)++;  // breaks here
 printf("Char is %c\n", a);

The following code works:

 char *tester = "hello";
 a = *tester;
 a++;
 printf("Char is %c\n", a);

 // prints i

Why can't it be done in one operation?

Blackfoot answered 15/3, 2016 at 20:28 Comment(1)
tester is a char *. (*tester) is a constant character. You are trying to increment a constant character.Bilk
L
12

It can be, you're just incrementing the wrong thing. (*tester)++ increments the data to which tester is pointing. I believe what you wish to do is *(++tester) which will increment the pointer and then dereference it.

Lepton answered 15/3, 2016 at 20:32 Comment(3)
Nit: *(tester++) evaluates to what tester is pointing to before the increment; it is logically equivalent to a = *tester; tester++. If you want the second character, you'd write *(++tester).Yerga
I want to increment 'h' to 'i'.Blackfoot
@JohnBode You are quite right. I've corrected my answerLepton
E
6
char *tester = "hello";

Here tester is pointing to a string constant. It is stored in a read-only memory. Any write modifications causes undefined behavior.

As @Taelsin pointed, it seems you want to increment the pointer itself, and not what it is pointing to. You need *(++tester).

After OP's clarification:

In case you want to increment the H to I, then (*tester + 1) would do the job.

Enrika answered 15/3, 2016 at 20:32 Comment(4)
Thanks. No I actually want to dereference 'h' and increment it to 'i'. I guess I don't understand why it's a string constant. Could you elaborate a bit?Blackfoot
Tester is a pointer to a string constant. Like char tester[]="Hello" is different from char *tester = "Hello"Enrika
@CorryChapman In C, string literals like "hello" are stored in read-only memory. You can't modify the contents of that string directly. This is why on sufficient warning levels assigning that string literal to a pointer-to-non-const (like you did) will emit warnings. You have to copy the string to a mutable array first if you want to modify the contents: char tester[] = "hello";Plassey
@zenith Detail: In C, attempting to write to the address of string literals like "hello" is undefined behavior. C does not define the type of memory in which "hello" is stored. It might be in read only memory, it might be in writable memory. it may fault. it is UB. "Hello" is properly called string literal.Suave
C
3

If you want to increment the character, you can add 1 to it instead of using the increment operator:

char *tester = "hello";
char a = (*tester) + 1; // instead of (*tester)++
printf("Char is %c\n", a);

Hope this is what you are searching for.

Explanation

In another answer, zenith commented an explanation why it is not possible to use the increment operator:

String literals like "hello" are initialized in a read-only memory. It is not possible to increment its value. That is why you have to copy the value first, if you want to change it. char a = (*tester) + 1; takes the value of the first character, adds 1 to it and saves it to a.

Cristiano answered 15/3, 2016 at 20:41 Comment(2)
Thanks. I see that works, but not clear why it can't be done in one go. It's a syntax question, rather than looking for a different way to do it.Blackfoot
@CorryChapman Because i++ is identical to i = i+1, so i is changed, while a = i+1 doesn't change i. Why does it matter? i is a character of a string literal, and changing it causes undefined behavior.Porterporterage
D
2

char a = (*tester)++; does not increase the pointer as you assume; it increases the dereferenced pointer instead, that is, the value a pointer points to.

You are actually trying to make changes to a string literal, which may resides in the read-only memory, causing undefined behaviour.

See n1570, 6.4.5 String literals:

7 It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.

To increase the pointer, use char a = *(tester++);, or just char a = *tester++; thanks to the operator precedence.

Declinature answered 15/3, 2016 at 23:24 Comment(0)
G
1

I guess you are trying to do something like this..

const char *tmp = "Hello world. This is a great test";
   int count = strlen(tmp);
   while(count>0)
   {
      printf("%s\n",tmp);
      tmp++;
      count--;
   }
Grubstake answered 7/11, 2017 at 15:26 Comment(0)
K
0

I think none of the answers fully answered op's question: op wanted to dereference 'h' to 'i', and he also wanted to know the reason that segmentFault came from his first code snippet

Combined above answers/comments, I list a full answer here:

A. op's first confusion comes from the concept difference between char s[] and char *s:

char *s="hello"; is to place "hello", the string literal, in the read-only memory and make s as a pointer to this string literal, making any writing operation illegal. While if define :

char s[]="hello"; is to put string literal in read-only memory and copy that string to another allocated memory on the stack, so that you can read/write directly on the stack memory (still, you are not touching read-only memory).

So dereference to char *test will given you a constant char, which is the first letter of a string literal located on read-only memory, that's the reason trying to char a = (*tester)++ will fail, because this is a pointer operation on read-only memory, the behavior is undefined.

B. why the second code snippet works ?

writing a = *tester; means you declare another variable char a, then on stack memory, allocate some space for a char and initialize its value to be 'h' ; This is equivalently to have below:

char a;
a = 'h';

Of course you can increment a.

Here is the example to the explicitly print out the address : run link

#include <stdio.h>

int main()
{
    char * tester = "hello";
    printf("tester first  letter address=%p\n",  tester);       // print out address should be something like 0x400648
    printf("tester second letter address=%p\n", (tester+1));    // print out address should be something like 0x400649

    char a;
    a = *tester;
    printf("a address=%p\n", &a);                               // print out address should be something like 0x7ffe0bc6aab7
    a++;        
    printf("a address=%p\n", &a);                               // print out address should be something like 0x7ffe0bc6aab7

    return 0;
}

Karlin answered 15/6, 2020 at 2:22 Comment(0)
R
0
 char *tester = "hello";

you are trying to create a pointer directly to a string here. which will result to unexpected behaviour(because its a read only space)

instead, what I would suggest you is to use character array.

Realgar answered 14/3, 2021 at 18:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.