Is it possible to modify a string of char in C?

前端 未结 9 1211
小蘑菇
小蘑菇 2020-11-22 09:08

I have been struggling for a few hours with all sorts of C tutorials and books related to pointers but what I really want to know is if it\'s possible to change a char point

相关标签:
9条回答
  • 2020-11-22 09:41

    All are good answers explaining why you cannot modify string literals because they are placed in read-only memory. However, when push comes to shove, there is a way to do this. Check out this example:

    #include <sys/mman.h>
    #include <unistd.h>
    #include <stddef.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    int take_me_back_to_DOS_times(const void *ptr, size_t len);
    
    int main()
    {
        const *data = "Bender is always sober.";
        printf("Before: %s\n", data);
        if (take_me_back_to_DOS_times(data, sizeof(data)) != 0)
            perror("Time machine appears to be broken!");
        memcpy((char *)data + 17, "drunk!", 6);
        printf("After: %s\n", data);
    
        return 0;
    }
    
    int take_me_back_to_DOS_times(const void *ptr, size_t len)
    {
        int pagesize;
        unsigned long long pg_off;
        void *page;
    
        pagesize = sysconf(_SC_PAGE_SIZE);
        if (pagesize < 0)
            return -1;
        pg_off = (unsigned long long)ptr % (unsigned long long)pagesize;
        page = ((char *)ptr - pg_off);
        if (mprotect(page, len + pg_off, PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
            return -1;
        return 0;
    }
    

    I have written this as part of my somewhat deeper thoughts on const-correctness, which you might find interesting (I hope :)).

    Hope it helps. Good Luck!

    0 讨论(0)
  • 2020-11-22 09:42

    A lot of folks get confused about the difference between char* and char[] in conjunction with string literals in C. When you write:

    char *foo = "hello world";
    

    ...you are actually pointing foo to a constant block of memory (in fact, what the compiler does with "hello world" in this instance is implementation-dependent.)

    Using char[] instead tells the compiler that you want to create an array and fill it with the contents, "hello world". foo is the a pointer to the first index of the char array. They both are char pointers, but only char[] will point to a locally allocated and mutable block of memory.

    0 讨论(0)
  • 2020-11-22 09:47

    The memory for a & b is not allocated by you. The compiler is free to choose a read-only memory location to store the characters. So if you try to change it may result in seg fault. So I suggest you to create a character array yourself. Something like: char a[10]; strcpy(a, "Hello");

    0 讨论(0)
  • 2020-11-22 09:48

    You need to copy the string into another, not read-only memory buffer and modify it there. Use strncpy() for copying the string, strlen() for detecting string length, malloc() and free() for dynamically allocating a buffer for the new string.

    For example (C++ like pseudocode):

    int stringLength = strlen( sourceString );
    char* newBuffer = malloc( stringLength + 1 );
    
    // you should check if newBuffer is 0 here to test for memory allocaton failure - omitted
    
    strncpy( newBuffer, sourceString, stringLength );
    newBuffer[stringLength] = 0;
    
    // you can now modify the contents of newBuffer freely
    
    free( newBuffer );
    newBuffer = 0;
    
    0 讨论(0)
  • 2020-11-22 09:52

    You could also use strdup:

       The strdup() function returns a pointer to a new string which is a duplicate of the string  s.
       Memory for the new string is obtained with malloc(3), and can be freed with free(3).
    

    For you example:

    char *a = strdup("stack overflow");
    
    0 讨论(0)
  • 2020-11-22 09:58

    It seems like your question has been answered but now you might wonder why char *a = "String" is stored in read-only memory. Well, it is actually left undefined by the c99 standard but most compilers choose to it this way for instances like:

    printf("Hello, World\n");
    

    c99 standard(pdf) [page 130, section 6.7.8]:

    The declaration:

    char s[] = "abc", t[3] = "abc";
    

    defines "plain" char array objects s and t whose elements are initialized with character string literals. This declaration is identical to char

    s[] = { 'a', 'b', 'c', '\0' }, t[] = { 'a', 'b', 'c' };
    

    The contents of the arrays are modifiable. On the other hand, the declaration

    char *p = "abc";
    

    defines p with type "pointer to char" and initializes it to point to an object with type "array of char" with length 4 whose elements are initialized with a character string literal. If an attempt is made to use p to modify the contents of the array, the behavior is undefined.

    0 讨论(0)
提交回复
热议问题