Search code examples
cstringsegmentation-faultconcatenationstring-concatenation

Concatenate strings without using string functions: Replacing the end of string (null character) gives seg fault


Without using the string.h functions (want to use only the std libs), I wanted to create a new string by concatenating the string provided as an argument to the program. For that, I decided to copy the argument to a new char array of larger size and then replace the end of the string by the characters I want to append.

unsigned int argsize=sizeof(argv[1]);
unsigned char *newstr=calloc(argsize+5,1);
newstr=argv[1];    //copied arg string to new string of larger size
newstr[argsize+4]=oname[ns];    //copied the end-of-string null character
newstr[argsize]='.';    //this line gives seg fault
newstr[argsize+1]='X';    //this executes without any error

I believe there must be another more secure way of concatenating string without using string functions or by copying and appending char by char into a new char array. I would really want to know such methods. Also, I'm curious to know what is the reason of this segfault. Read here: https://stackoverflow.com/a/164258/1176315 and I guess, the compiler is making my null character memory block read only but that's only a guess. I want to know the real reason behind this. I will appreciate all your efforts to answer the question. Thanks. Edit: By using std libs only, I mean to say I don't want to use the strcpy(), strlen(), strcat() etc. functions.


Solution

  • Without using the string.h functions (want to use only the std libs)

    string.h is part of the standard library.

    unsigned int argsize=sizeof(argv[1]);
    

    This is wrong. sizeof does not tell you the length of a C string, it just tell you how big is the type of its argument. argv[1] is a pointer, and sizeof will just tell you how big a pointer is on your platform (typically 4 or 8), regardless of the actual content of the string.

    If you want to know how long is a C string, you have to examine its characters and count until you find a 0 character (which incidentally is what strlen does).

    newstr=argv[1];    //copied arg string to new string of larger size
    

    Nope. You just copied the pointer stored in argv[1] to the variable newstr, incidentally losing the pointer that calloc returned to you previously, so you have also a memory leak.

    To copy a string from a buffer to another you have to copy its characters one by one until you find a 0 character (which incidentally is what strcpy does).

    All the following lines are thus operating on argv[1], so if you are going out of its original bounds anything can happen.

    I believe there must be another more secure way of concatenating string without using string functions or by copying and appending char by char into a new char array.

    C strings are just arrays of characters, everything boils down to copying/reading them one at time. If you don't want to use the provided string functions you'll end up essentially reimplementing them yourself. Mind you, it's a useful exercise, but you have to understand a bit better what C strings are and how pointers work.