LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 12-16-2006, 09:17 AM   #1
dayalan_cse
Member
 
Registered: Oct 2006
Posts: 132

Rep: Reputation: 15
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
 
Old 12-16-2006, 09:46 AM   #2
pigsa
Member
 
Registered: Nov 2003
Location: Hong Kong
Posts: 35
Blog Entries: 1

Rep: Reputation: 15
By assignment "data1" to dest, dest points to a buffer with 6 bytes, not 20 bytes.
 
Old 12-16-2006, 10:12 AM   #3
eerok
Member
 
Registered: Nov 2005
Location: Canada
Distribution: Mint, Debian
Posts: 168

Rep: Reputation: 32
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;
}
 
Old 12-17-2006, 02:22 AM   #4
dayalan_cse
Member
 
Registered: Oct 2006
Posts: 132

Original Poster
Rep: Reputation: 15
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.
 
Old 12-17-2006, 02:36 AM   #5
dayalan_cse
Member
 
Registered: Oct 2006
Posts: 132

Original Poster
Rep: Reputation: 15
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.
 
Old 12-17-2006, 02:55 AM   #6
BiThian
Member
 
Registered: Aug 2006
Location: Romania
Distribution: NetBSD 3.1
Posts: 118

Rep: Reputation: 15
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.
 
Old 12-17-2006, 03:12 AM   #7
introuble
Member
 
Registered: Apr 2004
Distribution: Debian -unstable
Posts: 700

Rep: Reputation: 31
:-/ 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.
 
Old 12-17-2006, 08:20 PM   #8
eerok
Member
 
Registered: Nov 2005
Location: Canada
Distribution: Mint, Debian
Posts: 168

Rep: Reputation: 32
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.

Last edited by eerok; 12-18-2006 at 01:54 AM.
 
Old 12-17-2006, 10:57 PM   #9
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
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;
}

Last edited by paulsm4; 12-17-2006 at 11:00 PM.
 
Old 12-18-2006, 01:37 AM   #10
eerok
Member
 
Registered: Nov 2005
Location: Canada
Distribution: Mint, Debian
Posts: 168

Rep: Reputation: 32
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.

Last edited by eerok; 12-18-2006 at 02:10 AM.
 
Old 12-18-2006, 02:42 AM   #11
duryodhan
Senior Member
 
Registered: Oct 2006
Distribution: Slackware 12 Kernel 2.6.24 - probably upgraded by now
Posts: 1,054

Rep: Reputation: 46
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.
 
Old 12-18-2006, 02:44 AM   #12
duryodhan
Senior Member
 
Registered: Oct 2006
Distribution: Slackware 12 Kernel 2.6.24 - probably upgraded by now
Posts: 1,054

Rep: Reputation: 46
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..
 
Old 12-18-2006, 04:51 AM   #13
dayalan_cse
Member
 
Registered: Oct 2006
Posts: 132

Original Poster
Rep: Reputation: 15
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
 
Old 12-18-2006, 04:59 AM   #14
BiThian
Member
 
Registered: Aug 2006
Location: Romania
Distribution: NetBSD 3.1
Posts: 118

Rep: Reputation: 15
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.
 
Old 12-18-2006, 05:35 AM   #15
matthewg42
Senior Member
 
Registered: Oct 2003
Location: UK
Distribution: Kubuntu 12.10 (using awesome wm though)
Posts: 3,530

Rep: Reputation: 65
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! */
    ...
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
segmentation fault? ferradura Slackware 3 07-05-2006 05:40 PM
yast segmentation fault, system freezing - nvidia driver at fault? BaltikaTroika SUSE / openSUSE 2 12-02-2005 09:34 AM
Segmentation fault velda.ebel Linux - Security 1 08-08-2005 07:23 PM
Segmentation fault Varadharajan Programming 5 04-22-2005 10:26 AM
segmentation fault for everything gsv Linux - Newbie 1 08-23-2004 06:19 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

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

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration