-2

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.

  • 2
    `sizeof(argv[1]);` is the size of a pointer, not the size of the string. `sizeof(argv[1]);` is not sensible code. – chux - Reinstate Monica Feb 04 '18 at 00:35
  • 3
    `newstr=argv[1]` doesn't copy the string. It overwrites the pointer, causing a memory leak. To copy a string, use the `strcpy` function (or write your own function that's equivalent to `strcpy`). – user3386109 Feb 04 '18 at 00:38
  • Why re-assign pointer `newstr` with `newstr=argv[1];` ? – chux - Reinstate Monica Feb 04 '18 at 00:38
  • @chux Maybe. Though it does give me the correct length of string to use it further in the code. When I print newstr char by char, after copying argv[1], it does print the argv[1] chars. But yeah, this may not be the correct way to do this. What would you suggest to do this? Thanks. And I didn't think I was reassigning the pointer! Thanks! – Ankur A Sharma Feb 04 '18 at 00:43
  • @user3386109 understood! Thanks! – Ankur A Sharma Feb 04 '18 at 00:44

2 Answers2

3

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.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
0

First of all sizeof(argv[1]) will not return the length of the string you need to count the number of characters in the string using loops or using standard library function strlen().second if you want to copy the string you need to use strcpy() function.

You supposed to do like this:

unsigned int argsize=strlen(argv[1]);  //you can also count the number of character
unsigned char *newstr=calloc((argsize+5),1);
strcpy(newstr,argv[1]);    
newstr[argsize+4]=oname[ns];    
newstr[argsize]='.'; 
newstr[argsize+1]='X';
krpra
  • 466
  • 1
  • 4
  • 19