LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   segmentation fault in strcpy (https://www.linuxquestions.org/questions/programming-9/segmentation-fault-in-strcpy-511057/)

dayalan_cse 12-16-2006 09:17 AM

segmentation fault in strcpy
 
#include<stdio.h>
#include<string.h>
#include<malloc.h>

int main()
{
char *dest;
char *in="String1";

dest=(char*) malloc(20);
dest="data1";
strcpy(dest,in);
printf("%s",dest);
free(dest);
return 0;
}

output:
Segmentation fault


thanks & regards
dayalan

pigsa 12-16-2006 09:46 AM

By assignment "data1" to dest, dest points to a buffer with 6 bytes, not 20 bytes.

eerok 12-16-2006 10:12 AM

Well, the problem is here:
Code:

dest=(char*) malloc(20);
dest="data1";

The buffer addr value dest gets from malloc() is trashed by the string assignment, so you might as well not have used malloc() at all.

This is the kind of thing you need to do:
Code:

#include<stdio.h>
#include<string.h>
#include<malloc.h>

int main (void)          /* don't use empty main() as per standard */
{
  char *dest;
  char *in = "String1";

  dest = malloc (20);    /* don't cast malloc */
  strcpy (dest,"data1");
  strcpy (dest,in);
  printf ("%s\n", dest);
  free (dest);
  return 0;
}


dayalan_cse 12-17-2006 02:22 AM

Quote:

Originally Posted by pigsa
By assignment "data1" to dest, dest points to a buffer with 6 bytes, not 20 bytes.

#include<stdio.h>
#include<string.h>
#include<malloc.h>

int main()
{
char *dest;
char *in="String1";

dest=(char*) malloc(20);
dest="data1 data1 data1 da"; --> now it is 20 bytes now also i am getting segmentation fault
strcpy(dest,in);
printf("%s",dest);
free(dest);
return 0;
}

output:
Segmentation fault

please give me some more information.

dayalan_cse 12-17-2006 02:36 AM

i have doubt in your answers can you please explain
 
Quote:

Originally Posted by eerok
Well, the problem is here:
Code:

dest=(char*) malloc(20);
dest="data1";

The buffer addr value dest gets from malloc() is trashed by the string assignment, so you might as well not have used malloc() at all.

i accept your point malloc address has been changed due to "data1" string assignment why i have to remove the "data1" initilize to dest variable. i have some reason by assigning some string to pointer the pointer address is pointed to where the string kept in memory. why the strcpy is not copying to this address from source to destination address.

This is the kind of thing you need to do:
Code:

#include<stdio.h>
#include<string.h>
#include<malloc.h>

int main (void)          /* don't use empty main() as per standard */
{
  char *dest;
  char *in = "String1";

  dest = malloc (20);   

/* don't cast malloc */ MALLOC WILL RETURN VOID* i think its better to  have (char*) typecasting. what do you say.


  strcpy (dest,"data1");
  strcpy (dest,in);
  printf ("%s\n", dest);
  free (dest);
  return 0;
}


please send me your answers.

BiThian 12-17-2006 02:55 AM

Here's my explanation:
Code:

dest="data1 data1 data1 da";
Tiil now, all is correct. You've just made pointer dest to point to location where the string "data1 data1 data1 da" is (statically) stored.
Code:

strcpy(dest,in);
Now, you made the mistake. You're trying to modify the string "data1 data1 data1 da", by using a pointer. This is WRONG! To alter the string content, dest must be an array.
Code:

char dest[n];
, where n is a value, works.

introuble 12-17-2006 03:12 AM

:-/ The OP doesn't contain any questions.. just a piece of code, the output and

Quote:

thanks & regards
dayalan
I fail to see what the author wants.

eerok 12-17-2006 08:20 PM

Quote:

Originally Posted by dayalan_cse
i accept your point malloc address has been changed due to "data1" string assignment why i have to remove the "data1" initilize to dest variable. i have some reason by assigning some string to pointer the pointer address is pointed to where the string kept in memory. why the strcpy is not copying to this address from source to destination address.

You don't initialize a buffer you've created with malloc(), you write to it, for the simple reason that only writing to it will work. (Sorry, mistake here: 'Your first try at assignment overwrote the pointer to your buffer because you needed to try '*dest' instead of 'dest' ... but even using the pointer properly in this case will still fail. Try it and see.')

Also you should try turning on warnings (gcc -Wall -Wextra). You will get a warning if you try the assignment above.

Quote:

/* don't cast malloc */ MALLOC WILL RETURN VOID* i think its better to have (char*) typecasting. what do you say.
All that matters with malloc() is the size of the block. Of course it returns a void pointer ... that means you don't have to cast it. The practice of casting malloc() is from the time before 'void' was implemented.

Put another way, once you assign the pointer from malloc to your variable that's been declared as a char pointer, what's left to worry about? Your char pointer is no less a char pointer.

paulsm4 12-17-2006 10:57 PM

More to the point, pigsa already gave you the answer to your original question, in the very first response:
Quote:

By assignment "data1" to dest, dest points to a buffer with 6 bytes, not 20 bytes.
Here is a corrected version of your original program:
Code:

#include <stdio.h>
#include <string.h>
#include <malloc.h>

int
main(int argc, char *argv[])
{
  static char *src = "data1";  /* This is 6 bytes (5 letters + null) of
                                  *READ-ONLY* string data.
                                  Don't even *THINK* of trying to
                                  write into "src"! */
  char *dest = malloc (strlen (src + 1)); /* This is N bytes of uninitialized,
                                          read/write data. */
  if (dest == NULL)
  {
    perror ("malloc failed!");
    return 1;
  }

  strcpy (dest, src);
  printf ("dest: %s\n", dest);

  free (dest);
  return 0;
}


eerok 12-18-2006 01:37 AM

Quote:

Originally Posted by paulsm4
More to the point, pigsa already gave you the answer to your original question, in the very first response:
Quote:

By assignment "data1" to dest, dest points to a buffer with 6 bytes, not 20 bytes.

That's not really the answer. The answer is that the assignment in question creates a string literal, which will cause a segfault when you try to overwrite it no matter how many bytes are involved. (String literals are stored in protected memory.)

I misexplained what was wrong in my remarks above, as I corrected.

Of course, you also get a segfault from 'free (dest);' after dest has been overwritten.

The result of a buffer overrun as mentioned would be "undefined behavior" ... it might work, crash, or segfault. I'm pretty sure the code didn't execute to that point, though.

When there's more than one thing wrong, it's sometimes hard to nail the pertinent one.

duryodhan 12-18-2006 02:42 AM

Quote:

dest="data1";
Therein lies the nub of the error.

use :
Quote:

strcpy(dest,"data1");
This I think, should work fine. Following that , the free will also work correctly.
Some teacher taught me to always use strcpy , use something like what you have done only when variable has been declared.

Someone posted dest should be an array. Thats not true IMHO; cos when you did malloc you did as much.

Sorry , my english is not that good and I dont have access to GCC right now, so all this is from top of my head.

duryodhan 12-18-2006 02:44 AM

Quote:

static char *src = "data1"; /* This is 6 bytes (5 letters + null) of
*READ-ONLY* string data.
Don't even *THINK* of trying to
write into "src"! */
I can think whatever I want :P

Seriously though, why can't I write into src?
from what I read, static is something which doesn't lose value between function calls..

dayalan_cse 12-18-2006 04:51 AM

Quote:

Originally Posted by duryodhan
I can think whatever I want :P

Seriously though, why can't I write into src?
from what I read, static is something which doesn't lose value between function calls..


hai duryodhan,

you are correct static is only preserve the values for the variable. but one thing i just want to remember you


" Someone posted dest should be an array. Thats not true IMHO; cos when you did malloc you did as much "

in the case of array the same code will goes through without segmentation fault. i have reason for you because when compiler does convert to object file that time the array is becomes read and write permissions but in the case of pointer i am assigning "data1" constant data this might has read permission but not for write so it causes segmentation fault occur. But still i need more information why pointer gaves me segmentation fault when i assinged "data1".

you want me to give program for the array implemented code?


Thanks & Regards
dayalan

BiThian 12-18-2006 04:59 AM

Quote:

Originally Posted by BiThian
Here's my explanation:
dest must be an array.
Code:

char dest[n];
, where n is a value, works.

I meant to say that:
Code:

char dest[]="this is just a test";
won't cause any segmentation fault.

PS: I really don't understand why some members keep saying stupidities, when I already explained what was the real problem.

matthewg42 12-18-2006 05:35 AM

When you do something like this:
Code:

char* c = "hello world";
...the compiler makes a static string "hello world" in the object file. This is in a read-only data segment (called .data). The variable named c, of type pointer to a char, is set to be the address of the first character of the string in the .data segment.

If you try to modify the address of the static string in the data segment, you get a segfault because that page of memory is marked as read-only.

So, in answer to the question "why does this make a segfault?", see comments here:
Code:

    dest=(char*) malloc(20);    /* After this, dest points to newly allocated
                                    memory from the heap (or NULL on failure) */
 
    dest="data1";                /* oops, you've discarded the address of your
                                    malloc'd memory, and instead set dest to
                                    point at the static string "data1" in the
                                    .data segment (readonly)! */

    strcpy(dest,in);            /* strcpy tries to write to the address of
                                    "data1".  Segfault! */
    ...



All times are GMT -5. The time now is 01:43 AM.