Why segmentation fault on implementation of strcpy? - c

I implement a simple strcpy, but when i run it , it always give a segmentation fault.
Please help!
Below is my code:
#include <stdio.h>
char* mystrcpy(char *dst, char *src){
char *ptr = dst;
while (*src !='\0') {
*dst = *src;
dst++;
src++;
}
return ptr;
}
int main (int argc, char **argv) {
char *str1 = "abc";
char *str2 = "def";
char *str3 = NULL;
str3 = mystrcpy(str2, str1);
printf("str2 now is %s", str2);
printf("str3 is %s", str3);
return 0;
}

These are read-only. Writing to them results in undefined behavior.
char *str1="abc"; /* Read-only. */
char *str2="def";
while (*src !='\0') {
*dst = *src; /* Writes into read-only memory. */
See this C FAQ:
String constants are in fact constant. The compiler may place them in
nonwritable storage, and it is therefore not safe to modify them.
And another explanation. You should try
char str1[]="abc";
char str2[]="def";

while( *src !='\0'){
*dst=*src;
You need to dereference your pointers here, using &, not *
EDIT:
Looks like I'm having my own personal cranial segmentation fault, here - too early in the morning!
cnicutar's explanation (assigning a pointer to a string constant with char *str2 = "def";, and then trying to write to that location) is much more plausible...

Related

Use of strcpy() in pointers to string in C

I'm trying to use strcpy() with pointers to strings and after a successful compilation when I run it it gives error. I don't know why this is happening.
int main()
{
char *s1="abcd";
char *s2="efgh";
strcpy(s2,s1);
printf("%s\n", s1);
printf("%s\n",s2);
getch();
}
These are string literals, you can't modify them because they're stored in read-only memory.
If you want to change this so you can modify them, use char s[]. This will store the strings on the stack:
char s1[] = "abcd";
char s2[] = "efgh";
If you want pointers to these, simply create pointers:
char *p1 = s1;
char *p2 = s2;
or you can create them with compound literals from C99:
char *p1 = (char []){"abcd"};
char *p2 = (char []){"efgh"};
A full program that puts the strings on the stack:
int main(void)
{
char s1[] = "abcd";
char s2[] = "efgh";
strcpy(s2, s1);
printf("%s\n", s1);
printf("%s\n", s2);
getchar();
}
Output:
abcd
abcd
You are trying to copy all content from first pointer string to second pointer string then I like to suggest you to use malloc
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char** argv) {
char *s1 ="abcd";
char *s2 ="efgh";
s2 = (char *) malloc(1 + strlen(s1));
strcpy(s2, s1);
printf("%s\n", s1);
printf("%s\n", s2);
return 0;
}
output -:abcd
abcd
hope this will fulfill your question

Copying string without strcpy using pointers

I'm trying to copy a string str into str using pointers. i think this can be achieved using a single pointer itself. whenever i run my code im getting str1 to display but with excessive unwanted garbage characters. please help. provide some insights
#include<stdio.h>
void main()
{
char str[10];
char str1[10];
printf("Enter a string");
scanf("%s",str);
char *p;
char *q;
int len=0,i=0;
p=&str;
q=&str;
while (*p!='\0')
{
len=len+1;
p=p+1;
}
printf("%d",len);
printf("\n");
while (len>0)
{
str1[i]=*q;
len=len-1;
}
printf("%s",str1);
}
str1[i] is always the same element because you never increment i. Thus all the other elements remain untouched and there is never an opportunity for the null terminator of q to be copied over.
Then, when you print it, the program has undefined behaviour.
It would probably be better to loop i from 0 to len.
You should also consider initialising your arrays with = {}, so that they contain nulls in the first place.
Furthermore, your scanf is extraordinarily unsafe as it performs no bounds checking.
Here you have an example:
char *mystrcpy(char *dest, const char *src)
{
char *saveddest = dest;
while(*src)
{
*dest++ = *src++;
}
*dest = 0;
return saveddest;
}
or
char *two_in_one_strcpy_strlen(char *dest, const char *src, size_t *len)
{
char *saveddest = dest;
*len = 0;
while(*src)
{
*dest++ = *src++;
*len++;
}
*dest = 0;
return saveddest;
}

Char *strcat Implementation leading to Segmentation Fault

char *strcat(char*dest, char*src) {
while (dest != '\0') {
*dest++;
}
while (src != '\0') {
*dest++ = *src++;
}
return dest;
}
I keep getting a segmentation fault on the line *dest++ = *src++. Any ideas on how to fix the problem?
Your code has 4 problems:
you are comparing pointers to the null character instead of comparing the character they point to. Since it will take incrementing the pointer an awful lot of times before it becomes 0, if at all, you are reading and/or writing beyond the end of the buffers, from/to invalid memory before this happens, hence the crash.
you do not null terminate the destination string.
you return the pointer to the end of the destination string instead of the original destination string. This might be a useful API, but you should use a different name for that.
the src pointer should be declared as const char * to conform to the standard declaration for this function and to allow passing pointers to constant strings as sources.
Here is a corrected version:
char *strcat(char *dest, const char *src) {
char *saved = dest;
while (*dest != '\0') {
dest++;
}
while ((*dest++ = *src++) != '\0') {
continue;
}
return saved;
}
Okay: the Kernighan way:
char *strcat(char *dest, char *src)
{
char *org = dest;
while(*dest++){;}
// at this moment, *dest MUST be pointing to '\0'
while(*dest++ = *src++){;}
// at this moment, *dest MUST be pointing to '\0' agian
return org;
}
Update (courtously #chqrlie):
char *strcat(char *dest, char *src)
{
char *org = dest;
for(; *dest; dest++) {;}
// at this moment, dest MUST be pointing to '\0'
while(*dest++ = *src++) {;}
// at this moment, dest points past the '\0', but who cares?
return org;
}
dest and source will never become '\0' if they aren't null to begin with (or maybe after a long time to be correct, but you'll probalby run out of memory long before that).
You should use:
while(*dest != '\0'){
dest++;
}
while(*src != '\0'){
*dest++ = *src++;
}
to check the values underneath the pointers.
There are some other problems too:
the resulting string is not null-terminated.
a pointer to the end of the string is returned.
As mentioned by others: src should be a const pointer too.
This should do it:
char *strcat(char *dest, const char *src)
{
char *start_pos = dest;
while(*dest != '\0')
dest++;
while(*src != '\0')
*dest++ = *src++;
*dest = '\0';
return start_pos;
}
Minor detail: I would give this funtion some other name than the standard used strcat().

Segmentation Fault with Pointers and Strings

I am writing a pointer version of the C function strcat. It copies the string t to the end of s. This is my solution:
/* strcat: a pointer version of the strcat (copy string t to the end of s) */
void strcat (char *s, char *t)
{
while (*s++ != '\0') /* find the end of s */
;
while (*s++ = *t++)
;
}
I ran it and it crashed - the Code Blocks debugger called it a segmentation fault, and that this part of the function was causing the crash:
while (*s++ = *t++)
What have I done wrong?
Here is the fixed version and a test program:
#include <stdio.h>
void strcat (char *s, char *t)
{
while (*s++)
;
s--;
while (*s++ = *t++)
;
}
int
main(void)
{
char str1[100] = "abc";
char *str2 = "def";
strcat(str1, str2);
printf("%s\n", str1);
return 0;
}
If you call that strcat() in the following way,
char *str1 = "abc";
char *str2 = "def";
strcat(str1, str2);
then your program may crash, because compilers usually put string literals in read-only memory region, try to write to these places will cause segment fault.

Segmentation Fault while trying to copy string in C function

I have a function in 'C' that is supposed to implement my own strcpy program. Here's what I wrote. However, I am not able to debug the cause of Segmentation Fault.
#include <stdio.h>
#include <stdlib.h>
char * mystrcpy(char *dest, char *src) {
char * ptr = dest;
while (*src != '\0'){
*ptr = *src;
ptr++; src++;
//printf("Dest is \"%s\" and Source is \"%s\"\n",dest,src);
}
*ptr = '\0';
return dest;
}
int main() {
char str[] = "I rock always";
char * dest = NULL;
dest = mystrcpy(dest, str);
printf("Source String %s and Destination String %s\n", str, dest);
}
Can someone explain this behavior to me ?
You have to allocate memory for the destination string:
int main() {
char str[] = "I rock always";
char * dest = (char*)malloc(strlen(str) + 1);
dest = mystrcpy(dest, str);
printf("Source String %s and Destination String %s\n", str, dest);
}
Of course, it is good manners to free the memory eventually:
free(dest);
You never allocate any memory for *dest to point to.
It starts pointing to NULL, and then you attempt: *ptr = *src.
#include <stdio.h>
/* this the K&R version of strcpy */
char * mystrcpy(char *dest, char *src) {
char *ptr = dest;
while ( *ptr++ = *src++ ) {;}
return dest;
}
int main(void) {
char str[] = "I rock always";
char dest[sizeof str];
char *result;
result = mystrcpy(dest, str);
printf("Source String %s and Destination String %s and result %s\n", str, dest, result);
return 0;
}
Allocate memory and try....
#include <stdio.h>
#include <stdlib.h>
char * mystrcpy(char *dest, char *src)
{
char * ptr = dest;
int index=0;
while (*src != '\0')
{
*(ptr+index) = *(src+index);
index++;
}
*(ptr+index) = '\0';
return dest;
}
int main()
{
char str[] = "I rock always";
char * dest = (char*)malloc((strlen(str)+1)*sizeof(char));
dest = mystrcpy(dest, str);
printf("Source String %s and Destination String %s\n", str, dest);
free(dest);
return 0;
}
You must allocate memory for the destination string buffer.
Memory management is a very big part of C ... you need to be very careful that you allocate AND deallocate memory as it is used and becomes surplus to requirements. Failure to do so will result in segmentation faults (failing to allocate memory) and memory leaks (failing to free memory)
Other answers here give you examples of malloc so I won't repeat them here.
You should use the functions already available to you as much as possible, rather than writing your own. This avoids errors in implementation as somebody has already debugged and optimized it for you.
http://www.cs.cf.ac.uk/Dave/C/node19.html

Resources