linux-c-programming.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* *w[1]++ = *[k[1]++; does not work .. ?
@ 2003-02-23 17:37 J.
  2003-02-23 19:30 ` Elias Athanasopoulos
  2003-02-24 16:02 ` *w[1]++ = *[k[1]++; does not work .. ? IVAN DE JESUS DERAS TABORA
  0 siblings, 2 replies; 7+ messages in thread
From: J. @ 2003-02-23 17:37 UTC (permalink / raw)
  To: linux-c-programming

Hello...

I am trying to copy a string into the first element of an array of char
pointers.

I can print char by char like this: printf("%c", *w[1]++);
but I can not copy char by char like this: *w[1]++ = *k[1]++;

I dont understand ? If I can print it, it should also copy ..

Strangly enough the compiler does not complain.

I have inserted a small illustrative example in this e-mail.

/* To illustrate the difference: This works */
#include <stdio.h>
#include <string.h>

int main(void) {
 char *w[1];
 char str[] = "jehova";

 w[1] = strdup(str);

 while(*w[1] != '\0')
  printf("%c", *w[1]++);

 printf("\n");
 return 0;
}

/* But this does not work */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
 char *w[1];
 char *k[1];
 char str[] = "jehova";

 w[1] = strdup(str);
 k[1] = calloc(strlen(str) + 1, sizeof(char));

 while(*w[1] != '\0')
  *k[1]++ = *w[1]++; 

 printf("%s\n", w[1]);
 return 0;
}

Can someone explain what I am doing wrong ?

Thankx a lot,...

J.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: *w[1]++ = *[k[1]++; does not work .. ?
  2003-02-23 17:37 *w[1]++ = *[k[1]++; does not work .. ? J.
@ 2003-02-23 19:30 ` Elias Athanasopoulos
  2003-02-24  7:55   ` J.
  2003-02-24 16:02 ` *w[1]++ = *[k[1]++; does not work .. ? IVAN DE JESUS DERAS TABORA
  1 sibling, 1 reply; 7+ messages in thread
From: Elias Athanasopoulos @ 2003-02-23 19:30 UTC (permalink / raw)
  To: J.; +Cc: linux-c-programming

On Sun, Feb 23, 2003 at 06:37:08PM +0100, J. wrote:
> I can print char by char like this: printf("%c", *w[1]++);
> but I can not copy char by char like this: *w[1]++ = *k[1]++;

It works.

>  while(*w[1] != '\0')
>   *k[1]++ = *w[1]++; 

You move the pointer while doing the copy, so after the loop it points to
the terminated null character.

You should keep the original address of k[1] before the loop and use it 
instead. I.e.:

	char *s;
	...
	s = k[1];

	while (...) { ... }
	
	printf ("%s\n", s);

You can do the copy more efficiantly using other ways. Check how strcpy()
works (it exists in K&R, glibc or even inside the kernel).

Elias

-- 
University of Athens			I bet the human brain 
Physics Department				is a kludge --Marvin Minsky 

	

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: *w[1]++ = *[k[1]++; does not work .. ?
  2003-02-23 19:30 ` Elias Athanasopoulos
@ 2003-02-24  7:55   ` J.
  2003-02-24  9:05     ` Elias Athanasopoulos
  0 siblings, 1 reply; 7+ messages in thread
From: J. @ 2003-02-24  7:55 UTC (permalink / raw)
  To: linux-c-programming

I am sorry, maybe I am not being to bright about this problem. But I still
do not see the clue.

On Sun, 23 Feb 2003, Elias Athanasopoulos wrote:

> On Sun, Feb 23, 2003 at 06:37:08PM +0100, J. wrote:
> > I can print char by char like this: printf("%c", *w[1]++);
> > but I can not copy char by char like this: *w[1]++ = *k[1]++;
> 
> It works.
> 
> >  while(*w[1] != '\0')
> >   *k[1]++ = *w[1]++; 
> 
> You move the pointer while doing the copy, so after the loop it points to
> the terminated null character.

Yes and then everything is copy'd, including the '\0' terminator just like
strcpy(). So k[1] should point to the character string and *k[1] points
to the first charater of the string ... ? 

> You should keep the original address of k[1] before the loop and use it 
> instead. I.e.:

The original address of *k[1] is preserved, only the memory segment
address it points to is incremented. I think...

> 	char *s;
> 	...
> 	s = k[1];
> 
> 	while (...) { ... }
> 	
> 	printf ("%s\n", s);
> 
> You can do the copy more efficiantly using other ways. Check how strcpy()
> works (it exists in K&R, glibc or even inside the kernel).
>
> Elias

Unfortunatly I can't use strcpy(), because I have to tokenze a string into
several sub-slices. One milion text lines (which is nothing), is prox. 14
milion words, is prox. 49 milion tokens. That is 49 milion strcpy's! So
this part could be classifyd as time-critical. I have a strcpy() version
and `gprof'd it. But the results were not very optimal. I was hoping by
just using pointers I could speed it up a little more.

But this is how my brain percieves this issue... Where do I go wrong ?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
             //  ___
 char *k[1]; // | 0 | -> 
             // |___|
             // | 1 | ->
             // |___|
             //  ___
 char *w[1]; // | 0 | ->
             // |___|
             // | 1 | ->
             // |___|

 char str[] = "jehova";
 /*
 --- --- --- --- --- --- ---
| j | e | h | o | v | a |\0|
 --- --- --- --- --- --- ---
 */

 w[1] = strdup(str);
 /*
  ___      --- --- --- --- --- --- ---
 | 0 | -> | j | e | h | o | v | a |\0|
 |___|     --- --- --- --- --- --- ---
 | 1 | -> NULL;
 |___|
 */

 k[1] = calloc(strlen(str) + 1, sizeof(char));
 /*
  ___      --- --- --- --- --- --- ---
 | 0 | -> |\0 |\0 |\0 |\0 |\0 |\0 |\0|
 |___|     --- --- --- --- --- --- ---
 | 1 | -> NULL;
 |___|
 */

 // Now for the copy part...
 // Eh.. ?
 while(*w[1] != '\0')
  *k[1]++ = *w[1]++; 

 // now k[1] should be:
 /*
  ___      --- --- --- --- --- --- ---
 | 0 | -> | j | e | h | o | v | a |\0|
 |___|     --- --- --- --- --- --- ---
 | 1 | -> NULL;
 |___|
 */

 // prints nothing....
 printf("%s\n", w[1]);
 printf("%s\n", k[1]);

 return 0;
}

Thank you for your patience...

J.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: *w[1]++ = *[k[1]++; does not work .. ?
@ 2003-02-24  8:21 Alvarez Alberto-AALVARB1
  0 siblings, 0 replies; 7+ messages in thread
From: Alvarez Alberto-AALVARB1 @ 2003-02-24  8:21 UTC (permalink / raw)
  To: linux-c-programming

Hi,
	just do what you've told to. Just an example to believe Elias:

...
	char *k[1];
	char *start;
...
	k[1] = calloc(strlen(str) + 1, sizeof(char));	
	start=k[1];
...
	printf("pointers: k=%ld start=%ld",k[1],start);
	k[1]=start;
	printf("and finally... %s",k[1]);


	you'll see the change that the value of k[1] has suffered after the loop. Now it points exactly to the '\0'.

	One thing else: as i can see, you shouldn't use k[1], since you've declared a 1-elment array. You should use k[0] instead. 

Regards,
	

Alberto Alvarez Besada

Tlf.:        +34 914002155
e-mail.:   aalvarb1@motorola.com
            


> -----Original Message-----
> From: J. [mailto:mailing-lists@xs4all.nl]
> Sent: lunes, 24 de febrero de 2003 8:55
> To: linux-c-programming@vger.kernel.org
> Subject: Re: *w[1]++ = *[k[1]++; does not work .. ?
> 
> 
> I am sorry, maybe I am not being to bright about this 
> problem. But I still
> do not see the clue.
> 
> On Sun, 23 Feb 2003, Elias Athanasopoulos wrote:
> 
> > On Sun, Feb 23, 2003 at 06:37:08PM +0100, J. wrote:
> > > I can print char by char like this: printf("%c", *w[1]++);
> > > but I can not copy char by char like this: *w[1]++ = *k[1]++;
> > 
> > It works.
> > 
> > >  while(*w[1] != '\0')
> > >   *k[1]++ = *w[1]++; 
> > 
> > You move the pointer while doing the copy, so after the 
> loop it points to
> > the terminated null character.
> 
> Yes and then everything is copy'd, including the '\0' 
> terminator just like
> strcpy(). So k[1] should point to the character string and 
> *k[1] points
> to the first charater of the string ... ? 
> 
> > You should keep the original address of k[1] before the 
> loop and use it 
> > instead. I.e.:
> 
> The original address of *k[1] is preserved, only the memory segment
> address it points to is incremented. I think...
> 
> > 	char *s;
> > 	...
> > 	s = k[1];
> > 
> > 	while (...) { ... }
> > 	
> > 	printf ("%s\n", s);
> > 
> > You can do the copy more efficiantly using other ways. 
> Check how strcpy()
> > works (it exists in K&R, glibc or even inside the kernel).
> >
> > Elias
> 
> Unfortunatly I can't use strcpy(), because I have to tokenze 
> a string into
> several sub-slices. One milion text lines (which is nothing), 
> is prox. 14
> milion words, is prox. 49 milion tokens. That is 49 milion 
> strcpy's! So
> this part could be classifyd as time-critical. I have a 
> strcpy() version
> and `gprof'd it. But the results were not very optimal. I was 
> hoping by
> just using pointers I could speed it up a little more.
> 
> But this is how my brain percieves this issue... Where do I go wrong ?
> 
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> 
> int main(void) {
>              //  ___
>  char *k[1]; // | 0 | -> 
>              // |___|
>              // | 1 | ->
>              // |___|
>              //  ___
>  char *w[1]; // | 0 | ->
>              // |___|
>              // | 1 | ->
>              // |___|
> 
>  char str[] = "jehova";
>  /*
>  --- --- --- --- --- --- ---
> | j | e | h | o | v | a |\0|
>  --- --- --- --- --- --- ---
>  */
> 
>  w[1] = strdup(str);
>  /*
>   ___      --- --- --- --- --- --- ---
>  | 0 | -> | j | e | h | o | v | a |\0|
>  |___|     --- --- --- --- --- --- ---
>  | 1 | -> NULL;
>  |___|
>  */
> 
>  k[1] = calloc(strlen(str) + 1, sizeof(char));
>  /*
>   ___      --- --- --- --- --- --- ---
>  | 0 | -> |\0 |\0 |\0 |\0 |\0 |\0 |\0|
>  |___|     --- --- --- --- --- --- ---
>  | 1 | -> NULL;
>  |___|
>  */
> 
>  // Now for the copy part...
>  // Eh.. ?
>  while(*w[1] != '\0')
>   *k[1]++ = *w[1]++; 
> 
>  // now k[1] should be:
>  /*
>   ___      --- --- --- --- --- --- ---
>  | 0 | -> | j | e | h | o | v | a |\0|
>  |___|     --- --- --- --- --- --- ---
>  | 1 | -> NULL;
>  |___|
>  */
> 
>  // prints nothing....
>  printf("%s\n", w[1]);
>  printf("%s\n", k[1]);
> 
>  return 0;
> }
> 
> Thank you for your patience...
> 
> J.
> 
> -
> To unsubscribe from this list: send the line "unsubscribe 
> linux-c-programming" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: *w[1]++ = *[k[1]++; does not work .. ?
  2003-02-24  7:55   ` J.
@ 2003-02-24  9:05     ` Elias Athanasopoulos
  2003-02-24  9:35       ` *w[1]++ = solved... thnkx... ? J.
  0 siblings, 1 reply; 7+ messages in thread
From: Elias Athanasopoulos @ 2003-02-24  9:05 UTC (permalink / raw)
  To: J.; +Cc: linux-c-programming

On Mon, Feb 24, 2003 at 08:55:16AM +0100, J. wrote:
> > On Sun, Feb 23, 2003 at 06:37:08PM +0100, J. wrote:
> > > I can print char by char like this: printf("%c", *w[1]++);
> > > but I can not copy char by char like this: *w[1]++ = *k[1]++;
> > 
> > It works.
> > 
> > >  while(*w[1] != '\0')
> > >   *k[1]++ = *w[1]++; 
> > 
> > You move the pointer while doing the copy, so after the loop it points to
> > the terminated null character.
> 
> Yes and then everything is copy'd, including the '\0' terminator just like
> strcpy(). So k[1] should point to the character string and *k[1] points
> to the first charater of the string ... ? 

*k[1] points nowhere since it's not a pointer; it's a character. Your pointer
is k[1] which is incremented in the loop, while making the contents of its
memory cells filled up with the characters belonging to w[1].

Try this (after the loop):

printf ("%c\n", *(k[1]-1)); 

It should print 'a'. The last char in jehova (if I'm spelling it right), before
the terminating '\0'.

Also, if you followed what I said, again after the loop:

printf ("%p %p\n", k[1], s);

You'll see how k[1] is different than s (remember before the loop they were pointing
in the exact mem address).

> > You should keep the original address of k[1] before the loop and use it 
> > instead. I.e.:
> 
> The original address of *k[1] is preserved, only the memory segment
> address it points to is incremented. I think...

No. *k[1] is the content of the mem address that k[1] points to. 

>  // now k[1] should be:
>  /*
>   ___      --- --- --- --- --- --- ---
>  | 0 | -> | j | e | h | o | v | a |\0|
>  |___|     --- --- --- --- --- --- ---

This is how the memory near k[1] is after the loop. But the original address
of k[1] has changed during the copy. If you subtruct the length of w[1] from
k[1] then you'll go back to the original point and do what you want to.


Elias

-- 
University of Athens			I bet the human brain 
Physics Department				is a kludge --Marvin Minsky 

	

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: *w[1]++ = solved... thnkx... ?
  2003-02-24  9:05     ` Elias Athanasopoulos
@ 2003-02-24  9:35       ` J.
  0 siblings, 0 replies; 7+ messages in thread
From: J. @ 2003-02-24  9:35 UTC (permalink / raw)
  To: linux-c-programming

On Mon, 24 Feb 2003, Elias Athanasopoulos wrote:

> On Mon, Feb 24, 2003 at 08:55:16AM +0100, J. wrote:
> > > On Sun, Feb 23, 2003 at 06:37:08PM +0100, J. wrote:
> > > > I can print char by char like this: printf("%c", *w[1]++);
> > > > but I can not copy char by char like this: *w[1]++ = *k[1]++;
> > > 
> > > It works.
> > > 
> > > >  while(*w[1] != '\0')
> > > >   *k[1]++ = *w[1]++; 
> > > 
> > > You move the pointer while doing the copy, so after the loop it points to
> > > the terminated null character.
> > 
> > Yes and then everything is copy'd, including the '\0' terminator just like
> > strcpy(). So k[1] should point to the character string and *k[1] points
> > to the first charater of the string ... ? 
> 
> *k[1] points nowhere since it's not a pointer; it's a character. Your pointer
> is k[1] which is incremented in the loop, while making the contents of its
> memory cells filled up with the characters belonging to w[1].

Now I understand!!!

> Try this (after the loop):
> 
> printf ("%c\n", *(k[1]-1)); 
> 
> It should print 'a'. The last char in jehova (if I'm spelling it right), before
> the terminating '\0'.
> 
> Also, if you followed what I said, again after the loop:
> 
> printf ("%p %p\n", k[1], s);
> 
> You'll see how k[1] is different than s (remember before the loop they were pointing
> in the exact mem address).

It suddenly all falls together and it makes sense...

> Elias

Great stuff.. Thankx.. again.. I'm going to fix right away..

J.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: *w[1]++ = *[k[1]++; does not work .. ?
  2003-02-23 17:37 *w[1]++ = *[k[1]++; does not work .. ? J.
  2003-02-23 19:30 ` Elias Athanasopoulos
@ 2003-02-24 16:02 ` IVAN DE JESUS DERAS TABORA
  1 sibling, 0 replies; 7+ messages in thread
From: IVAN DE JESUS DERAS TABORA @ 2003-02-24 16:02 UTC (permalink / raw)
  To: J.; +Cc: linux-c-programming

I think this is a common problem when you use arrays in C.  When you 
declare an array in C, using the following code:

int x[n];

The array will contain indexes from 0 to n-1, then when you declare an 
array char *k[1], it contain indexes from 0..0, when you try to access 
index 1, is an error because it isn't part of the array!!!!

I hope that this may be helpful.

J. wrote:

>Hello...
>
>I am trying to copy a string into the first element of an array of char
>pointers.
>
>I can print char by char like this: printf("%c", *w[1]++);
>but I can not copy char by char like this: *w[1]++ = *k[1]++;
>
>I dont understand ? If I can print it, it should also copy ..
>
>Strangly enough the compiler does not complain.
>
>I have inserted a small illustrative example in this e-mail.
>
>/* To illustrate the difference: This works */
>#include <stdio.h>
>#include <string.h>
>
>int main(void) {
> char *w[1];
> char str[] = "jehova";
>
> w[1] = strdup(str);
>
> while(*w[1] != '\0')
>  printf("%c", *w[1]++);
>
> printf("\n");
> return 0;
>}
>
>/* But this does not work */
>#include <stdio.h>
>#include <stdlib.h>
>#include <string.h>
>
>int main(void) {
> char *w[1];
> char *k[1];
> char str[] = "jehova";
>
> w[1] = strdup(str);
> k[1] = calloc(strlen(str) + 1, sizeof(char));
>
> while(*w[1] != '\0')
>  *k[1]++ = *w[1]++; 
>
> printf("%s\n", w[1]);
> return 0;
>}
>
>Can someone explain what I am doing wrong ?
>
>Thankx a lot,...
>
>J.
>
>-
>To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>
>  
>


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2003-02-24 16:02 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-02-23 17:37 *w[1]++ = *[k[1]++; does not work .. ? J.
2003-02-23 19:30 ` Elias Athanasopoulos
2003-02-24  7:55   ` J.
2003-02-24  9:05     ` Elias Athanasopoulos
2003-02-24  9:35       ` *w[1]++ = solved... thnkx... ? J.
2003-02-24 16:02 ` *w[1]++ = *[k[1]++; does not work .. ? IVAN DE JESUS DERAS TABORA
  -- strict thread matches above, loose matches on Subject: below --
2003-02-24  8:21 Alvarez Alberto-AALVARB1

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).