d2jsp
Log InRegister
d2jsp Forums > Off-Topic > Computers & IT > Programming & Development > Some Questions About A Small Piece Of C Code
12Next
Add Reply New Topic New Poll
Member
Posts: 4,841
Joined: Jan 16 2008
Gold: 0.00
Aug 20 2013 04:24am
Code
void copy(char to[], char from[]) {
   /* copy from from[] to to[], assumes sufficient space */
   int i = 0;
   while ((to[i] = from[i]) != '\0') {
       i++;
   }
}

int main() {
   char a[3] = {'h', 'a', '\n'};
   char b[3];
   printf("a: %s", a);
   copy(b, a);
   printf("a: %s", a);
   printf("b: %s", b);

   return 0;
}


1. Why does the copying of a to b work, despite a not ending with a '\0' as last entry?
2. Why does a get mutated in the process?

Thanks
Member
Posts: 2,478
Joined: Jan 4 2007
Gold: 7,545.00
Aug 20 2013 06:52am
Pretty sure the assignment happens before the bool check which is why the copy is working.
Member
Posts: 4,841
Joined: Jan 16 2008
Gold: 0.00
Aug 20 2013 08:20am
Quote (DirtyRasa @ Aug 20 2013 01:52pm)
Pretty sure the assignment happens before the bool check which is why the copy is working.

However, why is the while loop in copy even terminating when from[] has no '\0'?
Member
Posts: 16,144
Joined: Mar 27 2008
Gold: 14,618.00
Aug 20 2013 08:35am
Quote (tt_toby @ 20 Aug 2013 15:20)
However, why is the while loop in copy even terminating when from[] has no '\0'?

there is a chance that the next byte after the char array is a zero in memory.
it's not guaranteed to terminate... but sooner or later there will be a zero. the only question is, how many bytes it copies until it terminates.
Member
Posts: 4,841
Joined: Jan 16 2008
Gold: 0.00
Aug 20 2013 09:02am
I see, thanks. Seems like a dangerous assumption to make.
Now, why is a 'mutated' after the use of copy in my code example?
Member
Posts: 16,144
Joined: Mar 27 2008
Gold: 14,618.00
Aug 20 2013 09:34am
Quote (tt_toby @ 20 Aug 2013 16:02)
I see, thanks. Seems like a dangerous assumption to make.
Now, why is a 'mutated' after the  use of copy in my code example?


a is not mutated after the use of copy, when i use gcc 4.6.3

i assume you and your prof have another compiler and less luck :)
so i can only guess why a gets mutated in your case:

due to the lack of the 0x00, the copying later (after the copying of the normal 3 bytes) goes on and the variable i still counts up. i guess your 'a' gets overwridden. (buffer overflow)

-> use a decompiler or a debugger for a more precise analysis ^^
Member
Posts: 4,841
Joined: Jan 16 2008
Gold: 0.00
Aug 20 2013 09:44am
Quote (Richter @ Aug 20 2013 04:34pm)
a is not mutated after the use of copy, when i use gcc 4.6.3

i assume you and your prof have another compiler and less luck :)
so i can only guess why a gets mutated in your case:

due to the lack of the 0x00, the copying later (after the copying of the normal 3 bytes) goes on and the variable i still counts up. i guess your 'a' gets overwridden. (buffer overflow)

-> use a decompiler or a debugger for a more precise analysis ^^


Well, when I use gcc the following happens (check the comments):

Code
void copy(char to[], char from[]) {
   /* copy from from[] to to[], assumes sufficient space */
   int i = 0;
   while ((to[i] = from[i]) != '\0') {
       i++;
   }
   // printf("from[0]: %d\n", from[0]); // 0 -> NUL
   // printf("from[1]: %d\n", from[1]); // 97 -> h
   // printf("from[2]: %d\n", from[2]); // 10 -> LF
   // printf("from[3]: %d\n", from[3]); // 0 -> NUL
}

int main() {
   char a[3] = {'h', 'a', '\n'};
   char b[3];
   printf("a: %s", a); // prints ha
   copy(b, a);
   printf("a: %s", a); // prints nothing
   printf("b: %s", b); // prints ha

   return 0;
}


Member
Posts: 237
Joined: Aug 6 2011
Gold: 6,026.00
Aug 20 2013 11:27am
With lack of a null byte in your string you can expect undefined behavior as your counter pushes past the array size. Now, the behavior is usually compiler dependent. What you need to look at is the address of your arrays at each step. Most likely a and b are lined up and when you overwrite b in your copy function (i pushes past 2) it then writes over a.
Member
Posts: 1,358
Joined: Dec 30 2012
Gold: 0.10
Aug 20 2013 12:17pm
Code
void copy(char [], char[], unsigned short);

int main(int argc, const char * argv[])
{
   char a[4] = {'h', 'a', '\n'};
   char b[4];
   
   printf("a: %s", a); // prints ha
   copy(b, a, sizeof(a));
   printf("a: %s", a); // prints nothing
   printf("b: %s", b); // prints ha
   
   return 0;
}

void copy(char to[], char from[], unsigned short size) {
   /* copy from from[] to to[], assumes sufficient space */
   
   for(unsigned short i = 0; i  < size; ++i)
   {
       to[ i ] = from[ i ];
   }
   // printf("from[0]: %d\n", from[0]); // 0 -> NUL
   // printf("from[1]: %d\n", from[1]); // 97 -> h
   // printf("from[2]: %d\n", from[2]); // 10 -> LF
   // printf("from[3]: %d\n", from[3]); // 0 -> NUL
}


output

Code
a: ha
a: ha
b: ha


This post was edited by SelfTaught on Aug 20 2013 12:17pm
Member
Posts: 237
Joined: Aug 6 2011
Gold: 6,026.00
Aug 20 2013 01:14pm
Quote (SelfTaught @ Aug 20 2013 08:17pm)
Code
void copy(char [], char[], unsigned short);

int main(int argc, const char * argv[])
{
   char a[4] = {'h', 'a', '\n'};
   char b[4];
   
   printf("a: %s", a); // prints ha
   copy(b, a, sizeof(a));
   printf("a: %s", a); // prints nothing
   printf("b: %s", b); // prints ha
   
   return 0;
}

void copy(char to[], char from[], unsigned short size) {
   /* copy from from[] to to[], assumes sufficient space */
   
   for(unsigned short i = 0; i  < size; ++i)
   {
       to[ i ] = from[ i ];
   }
   // printf("from[0]: %d\n", from[0]); // 0 -> NUL
   // printf("from[1]: %d\n", from[1]); // 97 -> h
   // printf("from[2]: %d\n", from[2]); // 10 -> LF
   // printf("from[3]: %d\n", from[3]); // 0 -> NUL
}


output

Code
a: ha
a: ha
b: ha


have you tested this? cause it has 2 mistakes
Go Back To Programming & Development Topic List
12Next
Add Reply New Topic New Poll