views:

153

answers:

6
+1  Q: 

Segmentation fault

#include<stdio.h>
#include<zlib.h>
#include<unistd.h>
#include<string.h>


int main(int argc, char *argv[])
{
   char *path=NULL;
   size_t size;
   int index ;
   printf("\nArgument count is = %d", argc);
   printf ("\nThe 0th argument to the file is %s", argv[0]);
   path = getcwd(path, size);
   printf("\nThe current working directory is = %s", path);
   if (argc <= 1)
   {
      printf("\nUsage: ./output filename1 filename2 ...");
   }
   else if (argc > 1)
   {
      for (index = 1; index <= argc;index++)
      {
            printf("\n File name entered is = %s", argv[index]);
            strcat(path,argv[index]);
            printf("\n The complete path of the file name is = %s", path);
      }
   }
   return 0;
}

In the above code, here is the output that I get while running the code:

$ ./output test.txt

Argument count is = 2
The 0th argument to the file is ./output
The current working directory is = /home/welcomeuser
 File name entered is = test.txt
 The complete path of the file name is = /home/welcomeusertest.txt
Segmentation fault (core dumped)

Can anyone please me understand why I am getting a core dumped error?

Regards, darkie

+3  A: 

getcwd() allocates a buffer for path of the size equal to size. You did not initialize the size variable. Set it large enough to hold the whole path AND the name, and this should work. If the buffer is not large enough, the strcat() will write past the end of the buffer, overwriting other values on the stack (possibly including the function return pointer, which would cause a segfault on return).

Also, getcwd() uses malloc() to allocate the buffer you assign to path. It would be nice to free() this buffer when you're done with it. Though this is not strictly necessary at the end of the program - as the system will reclaim the memory anyway.

There are also some logic errors in your code. Firstly, the argv array indices range from 0 to argc-1. Your for loop exit condition makes you read one element past the end of the argv array.

Note that the strcat() will append a new parameter each iteration to the result of the previous iteration. This means that invoking /home$ ./output foo bar baz would end up with:

The complete path of the file name is = /home/foo
The complete path of the file name is = /home/foobar
The complete path of the file name is = /home/foobarbaz

Which is probably not what you want :). (omitted irrelevant lines of the output).

slacker
Maybe initializing `size` would be another good idea.
honk
getcwd() will malloc a buffer if you pass it a null pointer.
Fred Larson
@honk:Hah, true :).
slacker
@Fred Larson:Just searched the manpage - you're right. Though that's a nonstandard glibc extension. Now this explains why did it not segfault right at the beginning ;).
slacker
+4  A: 

The strcat is not valid. It is attempting to concatenate data to a buffer returned by the C runtime lib call. You need to use your own buffer. And you need to use free() on the buffer returned by getcwd() in the way that you are using it (passing in NULL causes it to allocate memory).

Mark Wilkins
Hi Mark,Can you please elaborate on your observation. I am a newbie to working on string operations and file operations on C. Any good resource to help me understand what you have pointed will be highly appreciated.Regards,darkie
darkie15
@darkie: I was looking at the man page on a linux box and it indicates that getcwd allocates a buffer with malloc if the given buffer is NULL. (http://linux.die.net/man/3/getcwd). It appears to be dependent on the version, though. The returned buffer, though, would likely not be long enough for new data to be appended. The strcat would add new data to that buffer and overwrite the the allocated space.
Mark Wilkins
+1  A: 

strcat(path,argv[index]) is adding data to a buffer that's not large enough to hold the additional data.

You should pass in a size value that will ensure the buffer is large enough. You're also not initializing size, so you really don't know what size buffer will be returned (all this is assuming that you're using the GNU libc version of getcwd() which will allocate a buffer if you pass in NULL).

Michael Burr
Apparently there are at least 2 bugs in your code. RichieHindle, Donal Fellows and Charles Bailey have identified another serious problem.
Michael Burr
Hi Michael,I am new to string and file operations in C. Any good resource to help me understand what needs to be done here will be highly appreciated.Regards,darkie
darkie15
Matt Jordan
+9  A: 

You are going off the end of argv by saying index <= argc. That should be index < argc. Remember, array indexes go from zero to one less than the length of the array.

(You're correct to start at 1, because argv[0] is the program name.)

RichieHindle
+1  A: 

You're reading off the end of argv. Don't do that. Stop at the argc-1'th argument.

Donal Fellows
+2  A: 

Although the answers about strcat are valid, given the point at which your program is crashing the issue is a NULL pointer deference because you use <= argc and not < argc.

In C, argv[argc] is a NULL pointer.

Charles Bailey