I am trying to concatenate multiple arguments passed via argv[] into a c-string. I'm not using a char array because I do not want any limits on the amount of characters passed through argv[].
This is an example of how I would execute my program.
executable -cmd rotn 13 Hello World
char *externalCommand = NULL;
if (argc >= 3 && strcmp(argv[1], "-cmd") == 0)
{
externalCommand = (char *)malloc(sizeof(char) * (strlen(argv[2]) + 1));
strcpy(externalCommand, argv[2]);
for (int i = 3; i < argc; ++i)
{
int textLength = strlen(externalCommand);
externalCommand = (char *)realloc(externalCommand, sizeof(char) * (textLength + 1));
strcpy(externalCommand + textLength, " ");
strcpy(externalCommand + textLength + 1, argv[i]);
}
}
My goal is to end of with the string "externalCommand" to be equal : "rotn 13 Hello World" When I go through the for loop for the first time, externalCommand is "rotn 13", which is normal.
When I go through the loop a second time, I get weird behaviour when I run realloc(). externalCommand becomes "rotn ÍÍÍýýýý««««««««îþîþ". I understand that these are garbage values, but I don't understand why realloc() overwrites the number "13" from my string.
To solve the issue, I can replace :
externalCommand = (char *)realloc(externalCommand, sizeof(char) * (textLength + 1));
with :
externalCommand = (char *)realloc(externalCommand, sizeof(char) * (textLength + 3));
which doesn't overwrite the value 13.
I would like to understand why do I need to add 3 to the textLength when reallocating.
Your realloc()
is not allocating enough memory to hold the data you are copying into the buffer. Use this instead:
externalCommand = (char *)realloc(externalCommand, sizeof(char) * (textLength + 1 + strlen(argv[i]) + 1));
That being said, if you precalculate the buffer size, you can get rid of realloc()
and use a single malloc()
:
char *externalCommand = NULL;
if (argc >= 3 && strcmp(argv[1], "-cmd") == 0)
{
int textlength = strlen(argv[2]);
for (int i = 3; i < argc; ++i)
textLength += (1 + strlen(argv[i]));
externalCommand = (char *)malloc(sizeof(char) * (textLength + 1));
strcpy(externalCommand, argv[2]);
for (int i = 3; i < argc; ++i)
{
strcat(externalCommand, " ");
strcat(externalCommand, argv[i]);
}
}