lmcintyre lmcintyre - 1 month ago 5
C Question

snprintf causing Abort trap 6 within function but not in main

I am having trouble understanding why this code executes the way it does. I fail to understand why when doThings executes, it gives me an Abort trap: 6 error, but when the loop within main executes, it does not give me an error and prints the valid portion of my character array (the value that can fit inside an array of size 30, the literal is 31 chars).

In short, the error is in the snprintf statement within doThings. Commenting it out breaks the code (obviously) but the Abort trap 6 does not occur. But why does it result in an an error there while executing without error in main?

#include <stdio.h>
#include <string.h>
#define BUF_LEN 30

void doThings(char *buffer)
{
char anotherBuffer[BUF_LEN];

int i;
for (i = 0; i <= BUF_LEN; i++)
{
char temp[2];

snprintf(temp, 2, "%s", buffer + i);

strcat(anotherBuffer, temp);
}

printf("%s\n", anotherBuffer);

}

int main()
{

char aString[BUF_LEN] = "1234567890123456789012345678901";

printf("%s\n", aString);

//This is doThings within main
int i;
for (i = 0; i <= BUF_LEN; i++)
{
char temp[2];

snprintf(temp, 2, "%s", aString + i);

printf("%s", temp);
}
printf("\n");

//Now execute doThings passing aString
doThings(aString);

return 0;
}

Answer

First of all, by saying

  char aString[BUF_LEN] = "1234567890123456789012345678901";

you're supplying a list of 31 chars as initializer to a 30-char array. That's not wrong as it is, but trying to use that char array as a string will lead to UB as there's no null-terminator in place.

Either define BUF_LEN as 32, or let the compiler decide the size, use something like

  char aString[ ] = "1234567890123456789012345678901";     

where compiler picks the correct size for the array as per the length of the supplied initializer, including the terminating null.

Then again, I believe, it has also to do with your looping condition. Instead of

 for (i = 0; i <= BUF_LEN; i++)

you should do

 for (i = 0; i < BUF_LEN; i++)

Otherwise, you'll be off-by-one as C arrays use 0-based indexing. By this, you'll be accessing out of bound memory which invokes undefined behavior.

Also, as rightly mentioned by Chux in the comments, you are using

 strcat(anotherBuffer, temp);

while anotherBuffer is uninitialized. By definition, the first argument of strcat() should be a pointer to a string, i.e., pointer to a null-terminated char array. At the very beginning, the content of anotherBuffer is indeterminate, let alone having a null-terminator. You should be initializing the automatic local variables always, like in this case,

char anotherBuffer[BUF_LEN] = {0};
Comments