简体   繁体   中英

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 .

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= %sp = %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.

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM