1

This produces the incorrect output.

Can someone tell me what I am doing wrong. The first 1,2 or 3 characters are displayed (depending on the chars) but the rest are random.

Note: This is just a learning exercise & am aware there are easier ways to do this.

int main(int argc, char *argv[])
{
  //Assume 1 arg only
  int len = strlen(argv[1]);
  char *d = malloc (strlen(argv[1])+1);
  strcpy(d,argv[1]);

  char *x;
  x = &d[0];

  int j,k;
  j = sizeof(char*);
  for (k=0;k<len;k++){
    printf("Value: %c\n\n", (*x + (k*j)));
}
ojhawkins
  • 3,200
  • 15
  • 50
  • 67

3 Answers3

2

you should use sizeof(char) which equals to 1; try this:

j = sizeof(char);
for (k = 0; k < len; k++ ) {
    printf("Value: %c\n\n", *(x + k * j)); // j equals to 1
}

Note: *(a + b) equals to a[b] or b[a]

frogatto
  • 28,539
  • 11
  • 83
  • 129
  • Note that `sizeof(char)` is guaranteed to be 1 so you don't need to use `j` at all – simonc Sep 28 '13 at 08:20
  • @simonc as he said this is a **learning exercise** not a real program – frogatto Sep 28 '13 at 08:21
  • 1
    @ABFORCE so @simonc comment is appropriate, since this is something that a newbie should learn soon (otherwise his real code could end up littered by `sizeof(char)`). – LorenzoDonati4Ukraine-OnStrike Sep 28 '13 at 08:24
  • @LorenzoDonati, you're right, but he MUST know `sizeof(char) == 1` and this is essential for advanced programming – frogatto Sep 28 '13 at 08:27
  • 1 question I have which im this discussion will answer. If a memory address is incremented by 1 say 0xa10 to 0xa11, how is a char stored at each address? does each address point to say 8 bytes for a 64 bit machine elsewhere? @LorenzoDonati – ojhawkins Sep 28 '13 at 08:33
  • Each char is stored continuously in memory. In your case x is char*, not char**, so the next element is at the next address. If x is char** which means each element is a pointer then you must use sizeof(char**) like your code – phuclv Sep 28 '13 at 08:57
  • @ojhawkins Maybe [this SO thread](http://stackoverflow.com/questions/15151377/what-exactly-is-a-c-pointer-if-not-a-memory-address) may help you. In short: using pointers you are not necessarily working with **memory** addresses. Any kind of computation you do with pointers is done using the semantics of pointer arithmetic, which depends on the exact type of the pointers involved. E.g. When you add `1` to a pointer to a char, you get a pointer to the next char (assuming the two are in the same array), regardless of how many memory bytes they are stored in (a C byte is not necessarily 8 bits!) – LorenzoDonati4Ukraine-OnStrike Sep 28 '13 at 09:02
1

There aren't sizeof(char*) bytes between characters in a string. You're also dereferencing the first character in the string then adding j*k to it. You should change your loop to

for (k=0;k<len;k++){
    printf("Value: %c\n\n", *(x + k));
}
simonc
  • 41,632
  • 12
  • 85
  • 103
1

Or you can just simply use pointer arithmetic to do this:

int len = strlen(argv[1]);
char *d = (char*)malloc (len+1);
strcpy(d,argv[1]);

char*p=d;
while(*p)
        printf("Value: %c\n\n", *p++);
free(d);

You also forgot to free the memory allocated by malloc. You need to call free at the end.

Zoli
  • 1,137
  • 7
  • 12
  • Can in do this? `if(*p++ == 'a')` @Zoltan – ojhawkins Sep 28 '13 at 09:53
  • Yes you can. It will compare the byte value pointed to by p to the byte value of 'a', then increment p to point to the next character in your string. The while loop will stop at the terminating '\0' (null) character and exit just as expected. – Zoli Sep 28 '13 at 10:30