Thread: const char* clarification

  1. #1
    Registered User
    Join Date
    May 2019
    Posts
    9

    const char* clarification

    Hello people!

    I need some clarification on a behaviour. I have this code:

    Code:
    const char *p = "TEST\n";
    p = "OTHER";
    printf("%s", p);
    This compiles fine and all, but I am not sure why. My "theory" is that "OTHER" is a string which is somewhere allocated, and then p points to it. This complies with the const char* type since it does not alter the "pointee", rather it points to another object all together!

    Is that correct?
    Last edited by Salem; 06-07-2019 at 04:19 AM. Reason: Removed crayola

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Here's what the compiler generates.
    Code:
    const char anon_s1[] = "TEST\n";
    const char anon_s2[] = "OTHER";
    
    
    const char *p = anon_s1;
    p = anon_s2;
    printf("%s", p);
    For each string constant, the compiler creates an anon_sx array for that string (it's a name you can never write in your C program).

    Such arrays exist for the life of the program, so there is no problem making a pointer point to different string constants at different times.

    Presumably, you have no confusion over
    Code:
    int a = 1;
    a = 42;
    printf("%d\n", a);
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    May 2019
    Posts
    9
    Aha, this clears it up! Thank you for insight

  4. #4
    Registered User catacombs's Avatar
    Join Date
    May 2019
    Location
    /home/
    Posts
    81
    Thanks, Salem. I didn't know assigning character arrays to pointers was possible. What I've always done was use strcpy to assign them.

  5. #5
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    Quote Originally Posted by catacombs View Post
    Thanks, Salem. I didn't know assigning character arrays to pointers was possible. What I've always done was use strcpy to assign them.
    i thought it was me being thick i didnt want to take over someone elses post though or appear to be arguing with salems explanation.

    im sure in the past i have had a char *name[10] and when i tried to write name[0] = "thomas" it wouldn't let me something about assignment to an array

  6. #6
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    Quote Originally Posted by cooper1200 View Post
    im sure in the past i have had a char *name[10] and when i tried to write name[0] = "thomas" it wouldn't let me something about assignment to an array
    I'm guessing you had char name[10]; and then tried to do name = "thomas";, which isn't allowed because name is an array, and you can't assign to an array.

  7. #7
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    nope definatly had *name in the end i had to use malloc and then strcpy it across

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Well, if you are so sure, post code that demonstrates your claim. Presently, I agree with christop: it sounds like you have forgotten what you wrote.

    Quote Originally Posted by catacombs
    I didn't know assigning character arrays to pointers was possible. What I've always done was use strcpy to assign them.
    It depends on what do you want: aliasing or copying?
    Last edited by laserlight; 06-07-2019 at 11:26 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    cant find the exact code but it was something along the lines of this with my first attempt at linked lists which i abandoned under your advice of keeping it simple with one data type.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct PERSON
    {
        int age;
        char *name[20]
    }PERSON;
    
    int main()
    {
        PERSON first_record;
    
        first_record.age = 34;
        first_record.name = "greg";
        return 0;
    }
    this produces the errors as follows
    Code:
    ||=== Build: Debug in array of pointer to strings (compiler: GNU GCC Compiler) ===|
    /home/ben/Documents/coding/array of pointer to strings/main.c|8|warning: no semicolon at end of struct or union|
    /home/ben/Documents/coding/array of pointer to strings/main.c||In function ‘main’:|
    /home/ben/Documents/coding/array of pointer to strings/main.c|15|error: assignment to expression with array type|
    /home/ben/Documents/coding/array of pointer to strings/main.c|12|warning: variable ‘first_record’ set but not used [-Wunused-but-set-variable]|
    ||=== Build failed: 1 error(s), 2 warning(s) (0 minute(s), 0 second(s)) ===|

  10. #10
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    updated code to get rid of the warnings
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct PERSON
    {
        int age;
        char *name[20];
    }PERSON;
    
    int main()
    {
        PERSON first_record;
    
        first_record.age = 34;
        first_record.name = "greg";
        printf("persons age is %d\n", first_record.age);
        return 0;
    }

  11. #11
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    found the code where i had to use strcpy etc
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    typedef struct Address
    {
        int door_number;
        char *street;
        char *city;
        struct Address *next;
    }Address;
     
    void add_address(Address *first, Address *current);
    void print_list(Address *first);
    void delete_list(Address *first);
     
    int main()
    {
        Address *first = NULL, *current = NULL;
     
        add_address(first, current);
        add_address(first, current);
        add_address(first, current);
        add_address(first, current);
        add_address(first, current);
     
        print_list(first);
        delete_list(first);
     
        return 0;
    }
    void add_address(Address *first, Address *current)
    {
        char my_str[20];
        Address *p_new_element;
     
        //get a new block of memmory and test the pointer isnt null
        p_new_element = malloc(sizeof(Address));
        if (!p_new_element)
        {
            printf("memmory allocation error");
            return;
        }
        //get door number and assign it to the new elements member 'door_number'
        printf("Please enter the door number: ");
        scanf(" %d", &p_new_element->door_number);
     
        //get street name and assign it to my_str
        printf("Please enter street name: ");
        scanf(" %s", my_str);
        //create memory for the street name and assign the pointer address->street to point to it
        p_new_element->street = malloc(strlen(my_str) + 1);
        //copy contents of my_str into the memmory location pointed to by address->street
        strcpy(p_new_element->street, my_str);
     
        //get city name
        printf("Please enter city name: ");
        scanf(" %s", my_str);
        //create memory for the city name and assign the pointer address->city to point to it
        p_new_element->city = malloc(strlen(my_str) + 1);
        //copy contents of my_str into the memmory location pointed to by address->city
        strcpy(p_new_element->city, my_str);
     
        if (first == NULL) // no list yet so make p_new_element the head
        {
            first = p_new_element;
            first->next = NULL;
            current = first;
            return;
        }
        if (first->next == NULL) //only one element in the list
        {
            first->next = p_new_element;
            current = p_new_element;
            current->next = NULL;
            return;
        }
        //more than 2 elements
        current->next = p_new_element;
        current = p_new_element;
        current->next = NULL;
    }
     
    void print_list(Address *first)
    {
        int count = 1;
        Address *temp = first;
     
        while (temp)
        {
            printf("address no %d is door number %d street %s city %s\n", count, temp->door_number,
                                                                           temp->street, temp->city);
            count++;
            temp = temp->next;
        }
    }
     
    void delete_list(Address *first)
    {
        int count = 1;
        Address *temp = NULL;
     
        printf("freeing memmory....\n");
        while (first)
        {
            temp = first->next; // set temp to point at the next element in the list
            printf("freeing element %d's street name\n", count);
            free(first->street); //free the memmory block that holds firsts street name
            printf("freeing element %d's city name\n", count);
            free(first->city); //free the memmory block that holds firsts city name
            printf("freeing struct %d's memmory\n", count);
            free(first); //free the memmory block that holds the first element
            first = temp; // set first to point at the next memmory block;
            count++;
        }
        printf("finished freeing all allocated memmory\n");
    }
    here is the link to the entire thread error subscripted value is neither an array nor pointer nor vector

  12. #12
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    Quote Originally Posted by cooper1200 View Post
    updated code to get rid of the warnings
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct PERSON
    {
        int age;
        char *name[20];
    }PERSON;
    
    int main()
    {
        PERSON first_record;
    
        first_record.age = 34;
        first_record.name = "greg";
        printf("persons age is %d\n", first_record.age);
        return 0;
    }
    You declare name (in struct PERSON) to be an array of 20 pointers to char. From your usage of name, that doesn't seem to be the correct type.

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    To put it another way: you said that you assigned to name[0], but that's because you forgot that you tried to assign to name rather than name[0].

    In the code that you finally found, you forgot that you had an array of char, not an array of char pointers.

    That is, in both cases you thought you did something similiar to what kaptsea demonstrated yet it didn't work, but actually you were doing fundamentally different things.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #14
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    and as i said to catacombs whom im sure you will agree understands more and is a better programmer than me i thought i was being thick but he mentioned he always used strcpy hence my post about needing to use strcpy in the above example

  15. #15
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    incidently isn't p_new_element->city a pointer of type char as p is in the original post so by that reasoning surely i could of just said p_new_element->city = my_str;

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 04-20-2011, 01:19 PM
  2. Replies: 3
    Last Post: 11-15-2009, 04:57 AM
  3. Difference between const char * and char const *
    By explorecpp in forum C Programming
    Replies: 4
    Last Post: 08-09-2008, 04:48 AM
  4. Replies: 7
    Last Post: 04-28-2008, 09:20 AM
  5. Assigning Const Char*s, Char*s, and Char[]s to wach other
    By Inquirer in forum Linux Programming
    Replies: 1
    Last Post: 04-29-2003, 10:52 PM

Tags for this Thread