Pen275 Pen275 - 2 months ago 10
C Question

C - Unusual Result When Intertwining Two Char Arrays

I'm working on a project that requires two strings to be "intertwined" together so that they alternate each character.
Example: "Apple" and "BEAR" would become "ABpEpAlRe"

This is my current function:

void printMessage(char name[], char num[])
{
char eticket[(sizeof(name)/sizeof(char))+((sizeof(num))/sizeof(char))] = ""; //make array with enough space for both strings
int i;
for(i=0;i<(sizeof(eticket)/sizeof(char));i++)
{
char tmp[1] ={name[i]}; // i have to change the char name[i] and num[i] to its own char array so i can use it in strcat
char tmp2[1] ={num[i]};
if(i<(sizeof(name)/sizeof(char))-1) //if name string is finished, don't concatenate
{
strcpy(eticket,strcat(eticket, tmp));
}
if(i<(sizeof(num)/sizeof(char))-1) //if num string is finished, don't concatenate
{
strcpy(eticket,strcat(eticket, tmp2));
}
}

printf("Your name is %s and your flight number is %s.\nYour e-ticket is: %s.\n\n", name, num, eticket);
}


Where eticket is the final string.

The result:

Your name is Connor and your flight number is MIA1050.
Your e-ticket is: CMMoIInAAn11o00r550.

*** stack smashing detected ***: ./a.out terminated
Aborted


I know stacking smashing means the buffer is being overflowed, but what concerns me more is that for some reason that I can't figure out, the num[] array is having its characters doubled in the final string.
Instead of "CMMoII..." it should be "CMoI..."
Is this perhaps a side effect of the buffer overflow?

Thanks in advance.

Answer

The others have pointed out that arrays are "passed by reference". So you should not use sizeof(name) because that's just sizeof(char*)(correct me if i'm wrong; always 8), but rather strlen(name).

char tmp[1] ={name[i]}; 
char tmp2[1] ={num[i]};

That might get you what you want, but its very redundant to create a char array for one element. Instead just create a char and pass a pointer to that char using the &:

char tmp = name[i];
printf("tmp: %s\n", &tmp);

The loop can be reduced to only two lines:

void printMessage(char* name, char* num){
   int len = strlen(name) + strlen(num);
   char* eticket = calloc(0,len +1); 
   int i,j,k;

   for(i=0, j=0, k=0; i<len;i++){
      if(j < strlen(name)) strncpy(&eticket[i++],&name[j++],1);
      if(k < strlen(num) ) strncpy(&eticket[i],&num[k++],1);
   }
   printf("Your name is %s and your flight number is %s.\nYour e-ticket is: %s.\n\n", name, num, eticket);
   free(eticket);
}

This does as you want it to, and is a lot cleaner. I skip the whole strcat(..) function, as its redundant. I use strncpy(char * dst, const char * src, size_t len) instead. How it works: - i keeps the position in the eticket. - j keeps the position in the name. - k keeps the position in the num.

&eticket[i++]

This points to the i'th position in the eticket array(i is incremented afterward). That means that the whatever is copied into this, will start here.

&name[j++]

This is a pointer to the j'th element in the name array. This means that strncpy will start reading here, and copy 1 element into the eticket array.

Hope this helps.

Comments