Select Call
Select Call

Reputation: 45

Arrays and pointer : segmentation fault

I am playing with array and pointer and got this segmentation fault. Can any one explain why I have been getting this segmentation fault in this code when I move my pointer "p" below "ptr" pointer in the code and when I comment out one of printf statement alternatively it disappears:

 typedef struct str{
   char* ptr;
  }str_t;

copy(str_t t){
   char a[12];
   char *p;   //  <------ no error when move below ptr pointer 
   char *ptr;

   printf("t= %s p = %d ptr = %d\n", t, p, ptr);

   strcpy(a, t.ptr);
   printf("a = %s %u\n", a, &a);

   strcpy(ptr, t.ptr);
   printf("ptr = %s %u\n", ptr, &ptr); //<--- comment it error disappears

   p= t.ptr;
   printf("p = %s %u",p, &p);  //<--- comment it error disappears
 }

int main ()
{
  str_t t;
  char app[] = "hello";
  char ap[] ="world";

  t.ptr = ap;
  copy(t);

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

  return 0;
}

you can compile the code here to see the result : http://codepad.org/Q7zS8NaC

Thank you , for visiting this question .

Upvotes: 0

Views: 1617

Answers (2)

tay10r
tay10r

Reputation: 4357

strcpy doesn't allocate space at the pointer, p, to store the string. You need to declare it as an array or allocate space with malloc or calloc.

Try this:

 int len = strlen (t.ptr);         // find length of string

 char * ptr = calloc (len + 1, 1); // allocate space for ptr
 if (!ptr) return;                 // error check calloc
 strcpy (ptr, t.ptr);              // copy the string

 char * p = calloc (len + 1, 1);   // do the same thing for p
 if (!p) return;
 strcpy (p, t.ptr);

That will fix your segmentation fault.

You have a couple of more errors though, which are mainly format issues.

  1. %u prints an unsigned integer. It looks like you're trying to print a pointer, so use %p instead.
  2. printf("t= %s p = %d ptr = %d\n", t, p, ptr); is totally wrong.
    1. You need to reference the member of t, which is t.ptr
    2. p is a pointer, not an integer. Use %p instead of %d
    3. ptr is also a pointer. Use either %p or %s

Read the documentation of printf if you're ever unsure about formatting. In fact, read the documentation of any function, if you are unsure how to use it - you'll save yourself a lot of headaches.

Upvotes: 5

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726569

Your code has several undefined behaviors:

  • The first printf prints a pointer using %d specifier
  • The second call of strcpy call attempts to write to memory pointed to by an uninitialized pointer
  • The second and third calls of printf passes a pointer to an array to a format specifier %u

Removing one of the pointers makes the code not crash, but since undefined behavior is there, the code does not work correctly, and may crash at any time.

Here is one way of fixing it:

char a[12];
char *p;
char *ptr;

printf("t= %s p = %x ptr = %x\n", t.ptr, (void*)p, (void*)ptr);

strcpy(a, t.ptr);
printf("a = %s %x\n", a, (void*)(&a[0]));
ptr = malloc(strlen(t.ptr)+1);
// In production, check ptr for NULL
strcpy(ptr, t.ptr);
printf("ptr = %s %x\n", ptr, (void*)&ptr);

p= t.ptr;
printf("p = %s %x", p, (void*)&p);
// Release the memory when you are done
free(ptr);

Upvotes: 2

Related Questions