Question

I have a string: "This is a simple string"

My objective is to find (with strstr) "simple" and replace it with "sample".

CODE:

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

int main (int argc, char *argv[]){
    char *str;
    char *pch;

    int i=0;

    if((str=malloc(BUFSIZ))==NULL){
        printf("\n\t MEMORY ERROR");
        exit(1);
    }
    if((pch=malloc(BUFSIZ))==NULL){
        printf("\n\t MEMORY ERROR");
        exit(1);
    }
    str="This is a simple string ";
    pch=str;
    while(str[i]!='\0'){
        printf("%c",str[i]);
        i++;
    }
    printf(" -1break\n");

    while((*pch!='\0')){
        printf("%c",*pch);
        pch++;
    }
    printf(" -2break\n");

    printf("%s %d %d %d %d\n",str,strlen(str),sizeof(*str),BUFSIZ,(BUFSIZ-strlen(str)));/*OK*/

    if((pch=strstr(str,"simple"))!=NULL){
        printf("%s \n",pch);     **/*OK*/**         
        while((*pch!='\0')){
            printf("%c",*pch);
            pch++;
        }                           **/*SEG FAULT*/**
    strncpy(pch,"sample",6);
    printf("OK\n");
    }
    printf("%s %d\n",str,strlen(str));
    printf("\n");
    return 0;
}

OUTPUT:

$ ./strstr

This is a simple string  -1break

This is a simple string  -2break

This is a simple string  24 1 8192 8168

simple string  

Segmentation fault

$ 

PROBLEM:

Can't replace "simple" with "sample".

QUESTION:

If pch points correctly to 's' of "simple" why cant strncpy replace the 6 letters of "sample"?

Was it helpful?

Solution

As summary your str pointer should point to a read/write memory area like memory allocated with malloc/calloc/realloc or static char array like char str[50] or char str[] = "simple string";

char *str = "simple string", str here is pointing to a literal string. And literal strings are stored in read only memory area so you can not edit it

Code critics:

1) first the following line is wrong

str="This is a simple string ";

you have allocated a memory for str and then you have not use it you have changed the pointer. The pointer now is pointing to a literal string (constant string) instead of its orgin memory area (allocated with malloc). it should be:

strcpy(str,"This is a simple string ");

the same for

pch = str;

pch is pointing to the same literal string of str

and

pch=strstr(str,"simple")

pch also here is pointing to a literal string because str is a literal sting

2) the following line is wrong

strncpy(pch,"sample",6);

pch is pointing to literal string and copy to a pointer pointing to literal string is undefined behaviour and this cause a crash

Code fixed:

int main (int argc, char *argv[]){
    char *str;
    char *pch;

    int i=0;

    if((str=malloc(BUFSIZ))==NULL){
        printf("\n\t MEMORY ERROR");
        exit(1);
    }

    strcpy (str, "This is a simple string ");
    if((pch=strstr(str,"simple"))!=NULL) {
        strncpy(pch,"sample",6);
    }
    printf("%s\n", str);
}

OTHER TIPS

Agree with Answer by MOHAMED. In addtion, the segmentation fault is caused as you have already moved "pch" to point to '\0', ie., end of string in the while loop before strncpy. strncpy is now writing beyond the end of literal string "This is a simple string", causing the segmentation fault. As pointed out by others, you are also causing a memory leak by re-assigning str (after malloc) to a literal string.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top