Pointers and access to memory in c. Be careful












14















Still learning more C and am a little confused. In my references I find cautions about assigning a pointer that has not been initialized. They go on to give examples. Great answers yesterday by the way from folks helping me with pointers, here:



Precedence, Parentheses, Pointers with iterative array functions



On follow up I briefly asked about the last iteration of the loop and potentially pointing the pointer to a non-existent place (i.e. because of my references cautioning against it). So I went back and looked more and find this:



If you have a pointer



int *pt;


then use it without initializing it (i.e. I take this to mean without a statement like *pt= &myVariable):



*pt = 606;


you could end up with a real bad day depending on where in memory this pointer has been assigned to. The part I'm having trouble with is when working with a string of characters something like this would be ok:



char *str = "Sometimes I feel like I'm going crazy.";


Where the reference says, "Don't worry about where in the memory the string is allocated; it's handled automatically by the compiler". So no need to say initialize *str = &str[0]; or *str = str;. Meaning, the compiler is automatically char str[n]; in the background?



Why is it that this is handled differently? Or, am I completely misunderstanding?










share|improve this question




















  • 1





    A string in C is a [null-terminated] array of characters. When a literal array is used in an assignment expression context it decays to a pointer to its first element. So, "Sometimes..." is equivalent to &"Sometimes..."[0].

    – DYZ
    Jan 3 at 16:22











  • Relevant earlier Q&A: stackoverflow.com/questions/27484168/…

    – Ilmari Karonen
    Jan 4 at 0:43


















14















Still learning more C and am a little confused. In my references I find cautions about assigning a pointer that has not been initialized. They go on to give examples. Great answers yesterday by the way from folks helping me with pointers, here:



Precedence, Parentheses, Pointers with iterative array functions



On follow up I briefly asked about the last iteration of the loop and potentially pointing the pointer to a non-existent place (i.e. because of my references cautioning against it). So I went back and looked more and find this:



If you have a pointer



int *pt;


then use it without initializing it (i.e. I take this to mean without a statement like *pt= &myVariable):



*pt = 606;


you could end up with a real bad day depending on where in memory this pointer has been assigned to. The part I'm having trouble with is when working with a string of characters something like this would be ok:



char *str = "Sometimes I feel like I'm going crazy.";


Where the reference says, "Don't worry about where in the memory the string is allocated; it's handled automatically by the compiler". So no need to say initialize *str = &str[0]; or *str = str;. Meaning, the compiler is automatically char str[n]; in the background?



Why is it that this is handled differently? Or, am I completely misunderstanding?










share|improve this question




















  • 1





    A string in C is a [null-terminated] array of characters. When a literal array is used in an assignment expression context it decays to a pointer to its first element. So, "Sometimes..." is equivalent to &"Sometimes..."[0].

    – DYZ
    Jan 3 at 16:22











  • Relevant earlier Q&A: stackoverflow.com/questions/27484168/…

    – Ilmari Karonen
    Jan 4 at 0:43
















14












14








14


1






Still learning more C and am a little confused. In my references I find cautions about assigning a pointer that has not been initialized. They go on to give examples. Great answers yesterday by the way from folks helping me with pointers, here:



Precedence, Parentheses, Pointers with iterative array functions



On follow up I briefly asked about the last iteration of the loop and potentially pointing the pointer to a non-existent place (i.e. because of my references cautioning against it). So I went back and looked more and find this:



If you have a pointer



int *pt;


then use it without initializing it (i.e. I take this to mean without a statement like *pt= &myVariable):



*pt = 606;


you could end up with a real bad day depending on where in memory this pointer has been assigned to. The part I'm having trouble with is when working with a string of characters something like this would be ok:



char *str = "Sometimes I feel like I'm going crazy.";


Where the reference says, "Don't worry about where in the memory the string is allocated; it's handled automatically by the compiler". So no need to say initialize *str = &str[0]; or *str = str;. Meaning, the compiler is automatically char str[n]; in the background?



Why is it that this is handled differently? Or, am I completely misunderstanding?










share|improve this question
















Still learning more C and am a little confused. In my references I find cautions about assigning a pointer that has not been initialized. They go on to give examples. Great answers yesterday by the way from folks helping me with pointers, here:



Precedence, Parentheses, Pointers with iterative array functions



On follow up I briefly asked about the last iteration of the loop and potentially pointing the pointer to a non-existent place (i.e. because of my references cautioning against it). So I went back and looked more and find this:



If you have a pointer



int *pt;


then use it without initializing it (i.e. I take this to mean without a statement like *pt= &myVariable):



*pt = 606;


you could end up with a real bad day depending on where in memory this pointer has been assigned to. The part I'm having trouble with is when working with a string of characters something like this would be ok:



char *str = "Sometimes I feel like I'm going crazy.";


Where the reference says, "Don't worry about where in the memory the string is allocated; it's handled automatically by the compiler". So no need to say initialize *str = &str[0]; or *str = str;. Meaning, the compiler is automatically char str[n]; in the background?



Why is it that this is handled differently? Or, am I completely misunderstanding?







c pointers






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 3 at 19:06









dbush

93.9k12101134




93.9k12101134










asked Jan 3 at 16:12









DanDan

16912




16912








  • 1





    A string in C is a [null-terminated] array of characters. When a literal array is used in an assignment expression context it decays to a pointer to its first element. So, "Sometimes..." is equivalent to &"Sometimes..."[0].

    – DYZ
    Jan 3 at 16:22











  • Relevant earlier Q&A: stackoverflow.com/questions/27484168/…

    – Ilmari Karonen
    Jan 4 at 0:43
















  • 1





    A string in C is a [null-terminated] array of characters. When a literal array is used in an assignment expression context it decays to a pointer to its first element. So, "Sometimes..." is equivalent to &"Sometimes..."[0].

    – DYZ
    Jan 3 at 16:22











  • Relevant earlier Q&A: stackoverflow.com/questions/27484168/…

    – Ilmari Karonen
    Jan 4 at 0:43










1




1





A string in C is a [null-terminated] array of characters. When a literal array is used in an assignment expression context it decays to a pointer to its first element. So, "Sometimes..." is equivalent to &"Sometimes..."[0].

– DYZ
Jan 3 at 16:22





A string in C is a [null-terminated] array of characters. When a literal array is used in an assignment expression context it decays to a pointer to its first element. So, "Sometimes..." is equivalent to &"Sometimes..."[0].

– DYZ
Jan 3 at 16:22













Relevant earlier Q&A: stackoverflow.com/questions/27484168/…

– Ilmari Karonen
Jan 4 at 0:43







Relevant earlier Q&A: stackoverflow.com/questions/27484168/…

– Ilmari Karonen
Jan 4 at 0:43














5 Answers
5






active

oldest

votes


















1














Simplifying the string literal can be expressed as:



const char literal = "Sometimes I feel like I'm going crazy."


so the expression



char *str = "Sometimes I feel like I'm going crazy.";


is logically equivalent to:



const char literal = "Sometimes I feel like I'm going crazy."
char *str = literal;


of course literals do not have the names



But you can't deference the char pointer which does not have allocated memory for the actual object



/* Wrong */
char *c;
*c = 'a';
/* Wrong - you assign the pointer with the integer value */
char *d = 'a';

/* Correct */
char *d = malloc(1);
*d = 'a';

/* Correct */
char x
char *e = &x;
*e = 'b';


The last example.



/* Wrong - you assign the pointer with the integer value */
int *p = 666;

/* Wrong oyu dereference the pointer which references to the not allocated space */
int *r;
*r = 666;

/* Correct */
int *s = malloc(sizeof(*s));
*s = 666;

/* Correct */
int t;
int *u = &t;
*u = 666;


And the last one - something similar to the string literals = the compound literals



/* Correct */
int *z = (int){666,567,234};
z[2] = 0;
*z = 5;

/* Correct */
int *z = (const int){666,567,234};





share|improve this answer


























  • Thank you @P_J_ this helps me also! I appreciate it!

    – Dan
    Jan 3 at 18:33











  • This actually helped me the most. I wasn't seeing the logical equivalency. Is it standard practice to leave out the explicit declaration of const char literal = "Sometimes I feel like I'm going crazy." ??? Or would it be better to use something like that? To me it is completely explicit and less confusing.

    – Dan
    Jan 7 at 15:24





















14














In this case:



char *str = "Sometimes I feel like I'm going crazy.";


You're initializing str to contain the address of the given string literal. You're not actually dereferencing anything at this point.



This is also fine:



char *str;
str = "Sometimes I feel like I'm going crazy.";


Because you're assigning to str and not actually dereferencing it.



This is a problem:



int *pt;
*pt = 606;


Because pt is not initialized and then it is dereferenced.



You also can't do this for the same reason (plus the types don't match):



*pt= &myVariable;


But you can do this:



pt= &myVariable;


After which you can freely use *pt.






share|improve this answer





















  • 3





    I take what you've written to mean: char *str = "Sometimes I feel like I'm going crazy."; does not = char *str; *str = "Sometimes I feel like I'm going crazy.";

    – Dan
    Jan 3 at 16:23








  • 1





    @Dan Correct. In the former case you initialize the pointer, in the latter case you dereference it.

    – dbush
    Jan 3 at 16:28











  • Starting to get it a little better! Appreciate all the help!

    – Dan
    Jan 3 at 20:03



















12














When you write sometype *p = something;, it's equivalent to sometype *p; p = something;, not sometype *p; *p = something;. That means when you use a string literal like that, the compiler figures out where to put it and then puts its address there.



The statement



char *str = "Sometimes I feel like I'm going crazy.";


is equivalent to



char *str;
str = "Sometimes I feel like I'm going crazy.";





share|improve this answer


























  • Thank you so much. both answers have helped my understanding greatly!

    – Dan
    Jan 3 at 16:29



















2














Good job on coming up with that example. It does a good job of showing the difference between declaring a pointer (like char *text;) and assigning to a pointer (like text = "Hello, World!";).



When you write:



char *text = "Hello!";


it is essentially the same as saying:



char *text;        /* Note the '*' before text */
text = "Hello!"; /* Note that there's no '*' on this line */


(Just so you know, the first line can also be written as char* text;.)



So why is there no * on the second line? Because text is of type char*, and "Hello!" is also of type char*. There is no disagreement here.



Also, the following three lines are identical, as far as the compiler is concerned:



char *text = "Hello!";
char* text = "Hello!";
char * text = "Hello!";


The placement of the space before or after the * makes no difference. The second line is arguably easier to read, as it drives the point home that text is a char*. (But be careful! This style can burn you if you declare more than one variable on a line!)



As for:



int *pt;
*pt = 606; /* Unsafe! */


you might say that *pt is an int, and so is 606, but it's more accurate to say that pt (without a *) is a pointer to memory that should contain an int. Whereas *pt (with a *) refers to the int inside the memory that pt (without the *) is pointing to.



And since pt was never initialized, using *pt (either to assign to or to de-reference) is unsafe.



Now, the interesting part about the lines:



int *pt;
*pt = 606; /* Unsafe! */


is that they'll compile (although possibly with a warning). That's because the compiler sees *pt as an int, and 606 as an int as well, so there's no disagreement. However, as written, the pointer pt doesn't point to any valid memory, so assigning to *pt will likely cause a crash, or corrupt data, or usher about the end of the world, etc.



It's important to realize that *pt is not a variable (even though it is often used like one). *pt just refers to the value in the memory whose address is contained in pt. Therefore, whether *pt is safe to use depends on whether pt contains a valid memory address. If pt isn't set to valid memory, then the use of *pt is unsafe.



So now you might be wondering: What's the point of declaring pt as an int* instead of just an int?



It depends on the case, but in many cases, there isn't any point.



When programming in C and C++, I use the advice: If you can get away with declaring a variable without making it a pointer, then you probably shouldn't declare it as a pointer.



Very often programmers use pointers when they don't need to. At the time, they aren't thinking of any other way. In my experience, when it's brought to their attention to not use a pointer, they will often say that it's impossible not to use a pointer. And when I prove them otherwise, they will usually backtrack and say that their code (which uses pointers) is more efficient than the code that doesn't use pointers.



(That's not true for all programmers, though. Some will recognize the appeal and simplicity of replacing a pointer with a non-pointer, and gladly change their code.)



I can't speak for all cases, of course, but C compilers these days are usually smart enough to compile both pointer code and non-pointer code to be practically identical in terms of efficiency. Not only that, but depending on the case, non-pointer code is often more efficient than code that uses pointers.






share|improve this answer

































    0














    Doing char *str = "I am a string"; means declaring and initializing an array of char. There's no problem since you're giving all the content of the array in the declaration.



    Doing int *pt = 606; is the same as doing char *str = 'a'; there's a problem: you're not giving enough information while declaring your variable.



    You need to do int nb = 606; int *pt = &nb; this way you give you pointer the address of the variable. Or if you want: you pass the int as an array of int.






    share|improve this answer





















    • 1





      There are a number of inaccuracies in this posting nor does it really answer the OP's question.

      – Richard Chambers
      Jan 3 at 16:35











    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54025987%2fpointers-and-access-to-memory-in-c-be-careful%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    5 Answers
    5






    active

    oldest

    votes








    5 Answers
    5






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    Simplifying the string literal can be expressed as:



    const char literal = "Sometimes I feel like I'm going crazy."


    so the expression



    char *str = "Sometimes I feel like I'm going crazy.";


    is logically equivalent to:



    const char literal = "Sometimes I feel like I'm going crazy."
    char *str = literal;


    of course literals do not have the names



    But you can't deference the char pointer which does not have allocated memory for the actual object



    /* Wrong */
    char *c;
    *c = 'a';
    /* Wrong - you assign the pointer with the integer value */
    char *d = 'a';

    /* Correct */
    char *d = malloc(1);
    *d = 'a';

    /* Correct */
    char x
    char *e = &x;
    *e = 'b';


    The last example.



    /* Wrong - you assign the pointer with the integer value */
    int *p = 666;

    /* Wrong oyu dereference the pointer which references to the not allocated space */
    int *r;
    *r = 666;

    /* Correct */
    int *s = malloc(sizeof(*s));
    *s = 666;

    /* Correct */
    int t;
    int *u = &t;
    *u = 666;


    And the last one - something similar to the string literals = the compound literals



    /* Correct */
    int *z = (int){666,567,234};
    z[2] = 0;
    *z = 5;

    /* Correct */
    int *z = (const int){666,567,234};





    share|improve this answer


























    • Thank you @P_J_ this helps me also! I appreciate it!

      – Dan
      Jan 3 at 18:33











    • This actually helped me the most. I wasn't seeing the logical equivalency. Is it standard practice to leave out the explicit declaration of const char literal = "Sometimes I feel like I'm going crazy." ??? Or would it be better to use something like that? To me it is completely explicit and less confusing.

      – Dan
      Jan 7 at 15:24


















    1














    Simplifying the string literal can be expressed as:



    const char literal = "Sometimes I feel like I'm going crazy."


    so the expression



    char *str = "Sometimes I feel like I'm going crazy.";


    is logically equivalent to:



    const char literal = "Sometimes I feel like I'm going crazy."
    char *str = literal;


    of course literals do not have the names



    But you can't deference the char pointer which does not have allocated memory for the actual object



    /* Wrong */
    char *c;
    *c = 'a';
    /* Wrong - you assign the pointer with the integer value */
    char *d = 'a';

    /* Correct */
    char *d = malloc(1);
    *d = 'a';

    /* Correct */
    char x
    char *e = &x;
    *e = 'b';


    The last example.



    /* Wrong - you assign the pointer with the integer value */
    int *p = 666;

    /* Wrong oyu dereference the pointer which references to the not allocated space */
    int *r;
    *r = 666;

    /* Correct */
    int *s = malloc(sizeof(*s));
    *s = 666;

    /* Correct */
    int t;
    int *u = &t;
    *u = 666;


    And the last one - something similar to the string literals = the compound literals



    /* Correct */
    int *z = (int){666,567,234};
    z[2] = 0;
    *z = 5;

    /* Correct */
    int *z = (const int){666,567,234};





    share|improve this answer


























    • Thank you @P_J_ this helps me also! I appreciate it!

      – Dan
      Jan 3 at 18:33











    • This actually helped me the most. I wasn't seeing the logical equivalency. Is it standard practice to leave out the explicit declaration of const char literal = "Sometimes I feel like I'm going crazy." ??? Or would it be better to use something like that? To me it is completely explicit and less confusing.

      – Dan
      Jan 7 at 15:24
















    1












    1








    1







    Simplifying the string literal can be expressed as:



    const char literal = "Sometimes I feel like I'm going crazy."


    so the expression



    char *str = "Sometimes I feel like I'm going crazy.";


    is logically equivalent to:



    const char literal = "Sometimes I feel like I'm going crazy."
    char *str = literal;


    of course literals do not have the names



    But you can't deference the char pointer which does not have allocated memory for the actual object



    /* Wrong */
    char *c;
    *c = 'a';
    /* Wrong - you assign the pointer with the integer value */
    char *d = 'a';

    /* Correct */
    char *d = malloc(1);
    *d = 'a';

    /* Correct */
    char x
    char *e = &x;
    *e = 'b';


    The last example.



    /* Wrong - you assign the pointer with the integer value */
    int *p = 666;

    /* Wrong oyu dereference the pointer which references to the not allocated space */
    int *r;
    *r = 666;

    /* Correct */
    int *s = malloc(sizeof(*s));
    *s = 666;

    /* Correct */
    int t;
    int *u = &t;
    *u = 666;


    And the last one - something similar to the string literals = the compound literals



    /* Correct */
    int *z = (int){666,567,234};
    z[2] = 0;
    *z = 5;

    /* Correct */
    int *z = (const int){666,567,234};





    share|improve this answer















    Simplifying the string literal can be expressed as:



    const char literal = "Sometimes I feel like I'm going crazy."


    so the expression



    char *str = "Sometimes I feel like I'm going crazy.";


    is logically equivalent to:



    const char literal = "Sometimes I feel like I'm going crazy."
    char *str = literal;


    of course literals do not have the names



    But you can't deference the char pointer which does not have allocated memory for the actual object



    /* Wrong */
    char *c;
    *c = 'a';
    /* Wrong - you assign the pointer with the integer value */
    char *d = 'a';

    /* Correct */
    char *d = malloc(1);
    *d = 'a';

    /* Correct */
    char x
    char *e = &x;
    *e = 'b';


    The last example.



    /* Wrong - you assign the pointer with the integer value */
    int *p = 666;

    /* Wrong oyu dereference the pointer which references to the not allocated space */
    int *r;
    *r = 666;

    /* Correct */
    int *s = malloc(sizeof(*s));
    *s = 666;

    /* Correct */
    int t;
    int *u = &t;
    *u = 666;


    And the last one - something similar to the string literals = the compound literals



    /* Correct */
    int *z = (int){666,567,234};
    z[2] = 0;
    *z = 5;

    /* Correct */
    int *z = (const int){666,567,234};






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jan 3 at 16:48

























    answered Jan 3 at 16:35









    P__J__P__J__

    9,3072723




    9,3072723













    • Thank you @P_J_ this helps me also! I appreciate it!

      – Dan
      Jan 3 at 18:33











    • This actually helped me the most. I wasn't seeing the logical equivalency. Is it standard practice to leave out the explicit declaration of const char literal = "Sometimes I feel like I'm going crazy." ??? Or would it be better to use something like that? To me it is completely explicit and less confusing.

      – Dan
      Jan 7 at 15:24





















    • Thank you @P_J_ this helps me also! I appreciate it!

      – Dan
      Jan 3 at 18:33











    • This actually helped me the most. I wasn't seeing the logical equivalency. Is it standard practice to leave out the explicit declaration of const char literal = "Sometimes I feel like I'm going crazy." ??? Or would it be better to use something like that? To me it is completely explicit and less confusing.

      – Dan
      Jan 7 at 15:24



















    Thank you @P_J_ this helps me also! I appreciate it!

    – Dan
    Jan 3 at 18:33





    Thank you @P_J_ this helps me also! I appreciate it!

    – Dan
    Jan 3 at 18:33













    This actually helped me the most. I wasn't seeing the logical equivalency. Is it standard practice to leave out the explicit declaration of const char literal = "Sometimes I feel like I'm going crazy." ??? Or would it be better to use something like that? To me it is completely explicit and less confusing.

    – Dan
    Jan 7 at 15:24







    This actually helped me the most. I wasn't seeing the logical equivalency. Is it standard practice to leave out the explicit declaration of const char literal = "Sometimes I feel like I'm going crazy." ??? Or would it be better to use something like that? To me it is completely explicit and less confusing.

    – Dan
    Jan 7 at 15:24















    14














    In this case:



    char *str = "Sometimes I feel like I'm going crazy.";


    You're initializing str to contain the address of the given string literal. You're not actually dereferencing anything at this point.



    This is also fine:



    char *str;
    str = "Sometimes I feel like I'm going crazy.";


    Because you're assigning to str and not actually dereferencing it.



    This is a problem:



    int *pt;
    *pt = 606;


    Because pt is not initialized and then it is dereferenced.



    You also can't do this for the same reason (plus the types don't match):



    *pt= &myVariable;


    But you can do this:



    pt= &myVariable;


    After which you can freely use *pt.






    share|improve this answer





















    • 3





      I take what you've written to mean: char *str = "Sometimes I feel like I'm going crazy."; does not = char *str; *str = "Sometimes I feel like I'm going crazy.";

      – Dan
      Jan 3 at 16:23








    • 1





      @Dan Correct. In the former case you initialize the pointer, in the latter case you dereference it.

      – dbush
      Jan 3 at 16:28











    • Starting to get it a little better! Appreciate all the help!

      – Dan
      Jan 3 at 20:03
















    14














    In this case:



    char *str = "Sometimes I feel like I'm going crazy.";


    You're initializing str to contain the address of the given string literal. You're not actually dereferencing anything at this point.



    This is also fine:



    char *str;
    str = "Sometimes I feel like I'm going crazy.";


    Because you're assigning to str and not actually dereferencing it.



    This is a problem:



    int *pt;
    *pt = 606;


    Because pt is not initialized and then it is dereferenced.



    You also can't do this for the same reason (plus the types don't match):



    *pt= &myVariable;


    But you can do this:



    pt= &myVariable;


    After which you can freely use *pt.






    share|improve this answer





















    • 3





      I take what you've written to mean: char *str = "Sometimes I feel like I'm going crazy."; does not = char *str; *str = "Sometimes I feel like I'm going crazy.";

      – Dan
      Jan 3 at 16:23








    • 1





      @Dan Correct. In the former case you initialize the pointer, in the latter case you dereference it.

      – dbush
      Jan 3 at 16:28











    • Starting to get it a little better! Appreciate all the help!

      – Dan
      Jan 3 at 20:03














    14












    14








    14







    In this case:



    char *str = "Sometimes I feel like I'm going crazy.";


    You're initializing str to contain the address of the given string literal. You're not actually dereferencing anything at this point.



    This is also fine:



    char *str;
    str = "Sometimes I feel like I'm going crazy.";


    Because you're assigning to str and not actually dereferencing it.



    This is a problem:



    int *pt;
    *pt = 606;


    Because pt is not initialized and then it is dereferenced.



    You also can't do this for the same reason (plus the types don't match):



    *pt= &myVariable;


    But you can do this:



    pt= &myVariable;


    After which you can freely use *pt.






    share|improve this answer















    In this case:



    char *str = "Sometimes I feel like I'm going crazy.";


    You're initializing str to contain the address of the given string literal. You're not actually dereferencing anything at this point.



    This is also fine:



    char *str;
    str = "Sometimes I feel like I'm going crazy.";


    Because you're assigning to str and not actually dereferencing it.



    This is a problem:



    int *pt;
    *pt = 606;


    Because pt is not initialized and then it is dereferenced.



    You also can't do this for the same reason (plus the types don't match):



    *pt= &myVariable;


    But you can do this:



    pt= &myVariable;


    After which you can freely use *pt.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jan 3 at 16:26

























    answered Jan 3 at 16:16









    dbushdbush

    93.9k12101134




    93.9k12101134








    • 3





      I take what you've written to mean: char *str = "Sometimes I feel like I'm going crazy."; does not = char *str; *str = "Sometimes I feel like I'm going crazy.";

      – Dan
      Jan 3 at 16:23








    • 1





      @Dan Correct. In the former case you initialize the pointer, in the latter case you dereference it.

      – dbush
      Jan 3 at 16:28











    • Starting to get it a little better! Appreciate all the help!

      – Dan
      Jan 3 at 20:03














    • 3





      I take what you've written to mean: char *str = "Sometimes I feel like I'm going crazy."; does not = char *str; *str = "Sometimes I feel like I'm going crazy.";

      – Dan
      Jan 3 at 16:23








    • 1





      @Dan Correct. In the former case you initialize the pointer, in the latter case you dereference it.

      – dbush
      Jan 3 at 16:28











    • Starting to get it a little better! Appreciate all the help!

      – Dan
      Jan 3 at 20:03








    3




    3





    I take what you've written to mean: char *str = "Sometimes I feel like I'm going crazy."; does not = char *str; *str = "Sometimes I feel like I'm going crazy.";

    – Dan
    Jan 3 at 16:23







    I take what you've written to mean: char *str = "Sometimes I feel like I'm going crazy."; does not = char *str; *str = "Sometimes I feel like I'm going crazy.";

    – Dan
    Jan 3 at 16:23






    1




    1





    @Dan Correct. In the former case you initialize the pointer, in the latter case you dereference it.

    – dbush
    Jan 3 at 16:28





    @Dan Correct. In the former case you initialize the pointer, in the latter case you dereference it.

    – dbush
    Jan 3 at 16:28













    Starting to get it a little better! Appreciate all the help!

    – Dan
    Jan 3 at 20:03





    Starting to get it a little better! Appreciate all the help!

    – Dan
    Jan 3 at 20:03











    12














    When you write sometype *p = something;, it's equivalent to sometype *p; p = something;, not sometype *p; *p = something;. That means when you use a string literal like that, the compiler figures out where to put it and then puts its address there.



    The statement



    char *str = "Sometimes I feel like I'm going crazy.";


    is equivalent to



    char *str;
    str = "Sometimes I feel like I'm going crazy.";





    share|improve this answer


























    • Thank you so much. both answers have helped my understanding greatly!

      – Dan
      Jan 3 at 16:29
















    12














    When you write sometype *p = something;, it's equivalent to sometype *p; p = something;, not sometype *p; *p = something;. That means when you use a string literal like that, the compiler figures out where to put it and then puts its address there.



    The statement



    char *str = "Sometimes I feel like I'm going crazy.";


    is equivalent to



    char *str;
    str = "Sometimes I feel like I'm going crazy.";





    share|improve this answer


























    • Thank you so much. both answers have helped my understanding greatly!

      – Dan
      Jan 3 at 16:29














    12












    12








    12







    When you write sometype *p = something;, it's equivalent to sometype *p; p = something;, not sometype *p; *p = something;. That means when you use a string literal like that, the compiler figures out where to put it and then puts its address there.



    The statement



    char *str = "Sometimes I feel like I'm going crazy.";


    is equivalent to



    char *str;
    str = "Sometimes I feel like I'm going crazy.";





    share|improve this answer















    When you write sometype *p = something;, it's equivalent to sometype *p; p = something;, not sometype *p; *p = something;. That means when you use a string literal like that, the compiler figures out where to put it and then puts its address there.



    The statement



    char *str = "Sometimes I feel like I'm going crazy.";


    is equivalent to



    char *str;
    str = "Sometimes I feel like I'm going crazy.";






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jan 3 at 16:26









    Richard Chambers

    9,61024066




    9,61024066










    answered Jan 3 at 16:15









    Joseph SibleJoseph Sible

    5,1732933




    5,1732933













    • Thank you so much. both answers have helped my understanding greatly!

      – Dan
      Jan 3 at 16:29



















    • Thank you so much. both answers have helped my understanding greatly!

      – Dan
      Jan 3 at 16:29

















    Thank you so much. both answers have helped my understanding greatly!

    – Dan
    Jan 3 at 16:29





    Thank you so much. both answers have helped my understanding greatly!

    – Dan
    Jan 3 at 16:29











    2














    Good job on coming up with that example. It does a good job of showing the difference between declaring a pointer (like char *text;) and assigning to a pointer (like text = "Hello, World!";).



    When you write:



    char *text = "Hello!";


    it is essentially the same as saying:



    char *text;        /* Note the '*' before text */
    text = "Hello!"; /* Note that there's no '*' on this line */


    (Just so you know, the first line can also be written as char* text;.)



    So why is there no * on the second line? Because text is of type char*, and "Hello!" is also of type char*. There is no disagreement here.



    Also, the following three lines are identical, as far as the compiler is concerned:



    char *text = "Hello!";
    char* text = "Hello!";
    char * text = "Hello!";


    The placement of the space before or after the * makes no difference. The second line is arguably easier to read, as it drives the point home that text is a char*. (But be careful! This style can burn you if you declare more than one variable on a line!)



    As for:



    int *pt;
    *pt = 606; /* Unsafe! */


    you might say that *pt is an int, and so is 606, but it's more accurate to say that pt (without a *) is a pointer to memory that should contain an int. Whereas *pt (with a *) refers to the int inside the memory that pt (without the *) is pointing to.



    And since pt was never initialized, using *pt (either to assign to or to de-reference) is unsafe.



    Now, the interesting part about the lines:



    int *pt;
    *pt = 606; /* Unsafe! */


    is that they'll compile (although possibly with a warning). That's because the compiler sees *pt as an int, and 606 as an int as well, so there's no disagreement. However, as written, the pointer pt doesn't point to any valid memory, so assigning to *pt will likely cause a crash, or corrupt data, or usher about the end of the world, etc.



    It's important to realize that *pt is not a variable (even though it is often used like one). *pt just refers to the value in the memory whose address is contained in pt. Therefore, whether *pt is safe to use depends on whether pt contains a valid memory address. If pt isn't set to valid memory, then the use of *pt is unsafe.



    So now you might be wondering: What's the point of declaring pt as an int* instead of just an int?



    It depends on the case, but in many cases, there isn't any point.



    When programming in C and C++, I use the advice: If you can get away with declaring a variable without making it a pointer, then you probably shouldn't declare it as a pointer.



    Very often programmers use pointers when they don't need to. At the time, they aren't thinking of any other way. In my experience, when it's brought to their attention to not use a pointer, they will often say that it's impossible not to use a pointer. And when I prove them otherwise, they will usually backtrack and say that their code (which uses pointers) is more efficient than the code that doesn't use pointers.



    (That's not true for all programmers, though. Some will recognize the appeal and simplicity of replacing a pointer with a non-pointer, and gladly change their code.)



    I can't speak for all cases, of course, but C compilers these days are usually smart enough to compile both pointer code and non-pointer code to be practically identical in terms of efficiency. Not only that, but depending on the case, non-pointer code is often more efficient than code that uses pointers.






    share|improve this answer






























      2














      Good job on coming up with that example. It does a good job of showing the difference between declaring a pointer (like char *text;) and assigning to a pointer (like text = "Hello, World!";).



      When you write:



      char *text = "Hello!";


      it is essentially the same as saying:



      char *text;        /* Note the '*' before text */
      text = "Hello!"; /* Note that there's no '*' on this line */


      (Just so you know, the first line can also be written as char* text;.)



      So why is there no * on the second line? Because text is of type char*, and "Hello!" is also of type char*. There is no disagreement here.



      Also, the following three lines are identical, as far as the compiler is concerned:



      char *text = "Hello!";
      char* text = "Hello!";
      char * text = "Hello!";


      The placement of the space before or after the * makes no difference. The second line is arguably easier to read, as it drives the point home that text is a char*. (But be careful! This style can burn you if you declare more than one variable on a line!)



      As for:



      int *pt;
      *pt = 606; /* Unsafe! */


      you might say that *pt is an int, and so is 606, but it's more accurate to say that pt (without a *) is a pointer to memory that should contain an int. Whereas *pt (with a *) refers to the int inside the memory that pt (without the *) is pointing to.



      And since pt was never initialized, using *pt (either to assign to or to de-reference) is unsafe.



      Now, the interesting part about the lines:



      int *pt;
      *pt = 606; /* Unsafe! */


      is that they'll compile (although possibly with a warning). That's because the compiler sees *pt as an int, and 606 as an int as well, so there's no disagreement. However, as written, the pointer pt doesn't point to any valid memory, so assigning to *pt will likely cause a crash, or corrupt data, or usher about the end of the world, etc.



      It's important to realize that *pt is not a variable (even though it is often used like one). *pt just refers to the value in the memory whose address is contained in pt. Therefore, whether *pt is safe to use depends on whether pt contains a valid memory address. If pt isn't set to valid memory, then the use of *pt is unsafe.



      So now you might be wondering: What's the point of declaring pt as an int* instead of just an int?



      It depends on the case, but in many cases, there isn't any point.



      When programming in C and C++, I use the advice: If you can get away with declaring a variable without making it a pointer, then you probably shouldn't declare it as a pointer.



      Very often programmers use pointers when they don't need to. At the time, they aren't thinking of any other way. In my experience, when it's brought to their attention to not use a pointer, they will often say that it's impossible not to use a pointer. And when I prove them otherwise, they will usually backtrack and say that their code (which uses pointers) is more efficient than the code that doesn't use pointers.



      (That's not true for all programmers, though. Some will recognize the appeal and simplicity of replacing a pointer with a non-pointer, and gladly change their code.)



      I can't speak for all cases, of course, but C compilers these days are usually smart enough to compile both pointer code and non-pointer code to be practically identical in terms of efficiency. Not only that, but depending on the case, non-pointer code is often more efficient than code that uses pointers.






      share|improve this answer




























        2












        2








        2







        Good job on coming up with that example. It does a good job of showing the difference between declaring a pointer (like char *text;) and assigning to a pointer (like text = "Hello, World!";).



        When you write:



        char *text = "Hello!";


        it is essentially the same as saying:



        char *text;        /* Note the '*' before text */
        text = "Hello!"; /* Note that there's no '*' on this line */


        (Just so you know, the first line can also be written as char* text;.)



        So why is there no * on the second line? Because text is of type char*, and "Hello!" is also of type char*. There is no disagreement here.



        Also, the following three lines are identical, as far as the compiler is concerned:



        char *text = "Hello!";
        char* text = "Hello!";
        char * text = "Hello!";


        The placement of the space before or after the * makes no difference. The second line is arguably easier to read, as it drives the point home that text is a char*. (But be careful! This style can burn you if you declare more than one variable on a line!)



        As for:



        int *pt;
        *pt = 606; /* Unsafe! */


        you might say that *pt is an int, and so is 606, but it's more accurate to say that pt (without a *) is a pointer to memory that should contain an int. Whereas *pt (with a *) refers to the int inside the memory that pt (without the *) is pointing to.



        And since pt was never initialized, using *pt (either to assign to or to de-reference) is unsafe.



        Now, the interesting part about the lines:



        int *pt;
        *pt = 606; /* Unsafe! */


        is that they'll compile (although possibly with a warning). That's because the compiler sees *pt as an int, and 606 as an int as well, so there's no disagreement. However, as written, the pointer pt doesn't point to any valid memory, so assigning to *pt will likely cause a crash, or corrupt data, or usher about the end of the world, etc.



        It's important to realize that *pt is not a variable (even though it is often used like one). *pt just refers to the value in the memory whose address is contained in pt. Therefore, whether *pt is safe to use depends on whether pt contains a valid memory address. If pt isn't set to valid memory, then the use of *pt is unsafe.



        So now you might be wondering: What's the point of declaring pt as an int* instead of just an int?



        It depends on the case, but in many cases, there isn't any point.



        When programming in C and C++, I use the advice: If you can get away with declaring a variable without making it a pointer, then you probably shouldn't declare it as a pointer.



        Very often programmers use pointers when they don't need to. At the time, they aren't thinking of any other way. In my experience, when it's brought to their attention to not use a pointer, they will often say that it's impossible not to use a pointer. And when I prove them otherwise, they will usually backtrack and say that their code (which uses pointers) is more efficient than the code that doesn't use pointers.



        (That's not true for all programmers, though. Some will recognize the appeal and simplicity of replacing a pointer with a non-pointer, and gladly change their code.)



        I can't speak for all cases, of course, but C compilers these days are usually smart enough to compile both pointer code and non-pointer code to be practically identical in terms of efficiency. Not only that, but depending on the case, non-pointer code is often more efficient than code that uses pointers.






        share|improve this answer















        Good job on coming up with that example. It does a good job of showing the difference between declaring a pointer (like char *text;) and assigning to a pointer (like text = "Hello, World!";).



        When you write:



        char *text = "Hello!";


        it is essentially the same as saying:



        char *text;        /* Note the '*' before text */
        text = "Hello!"; /* Note that there's no '*' on this line */


        (Just so you know, the first line can also be written as char* text;.)



        So why is there no * on the second line? Because text is of type char*, and "Hello!" is also of type char*. There is no disagreement here.



        Also, the following three lines are identical, as far as the compiler is concerned:



        char *text = "Hello!";
        char* text = "Hello!";
        char * text = "Hello!";


        The placement of the space before or after the * makes no difference. The second line is arguably easier to read, as it drives the point home that text is a char*. (But be careful! This style can burn you if you declare more than one variable on a line!)



        As for:



        int *pt;
        *pt = 606; /* Unsafe! */


        you might say that *pt is an int, and so is 606, but it's more accurate to say that pt (without a *) is a pointer to memory that should contain an int. Whereas *pt (with a *) refers to the int inside the memory that pt (without the *) is pointing to.



        And since pt was never initialized, using *pt (either to assign to or to de-reference) is unsafe.



        Now, the interesting part about the lines:



        int *pt;
        *pt = 606; /* Unsafe! */


        is that they'll compile (although possibly with a warning). That's because the compiler sees *pt as an int, and 606 as an int as well, so there's no disagreement. However, as written, the pointer pt doesn't point to any valid memory, so assigning to *pt will likely cause a crash, or corrupt data, or usher about the end of the world, etc.



        It's important to realize that *pt is not a variable (even though it is often used like one). *pt just refers to the value in the memory whose address is contained in pt. Therefore, whether *pt is safe to use depends on whether pt contains a valid memory address. If pt isn't set to valid memory, then the use of *pt is unsafe.



        So now you might be wondering: What's the point of declaring pt as an int* instead of just an int?



        It depends on the case, but in many cases, there isn't any point.



        When programming in C and C++, I use the advice: If you can get away with declaring a variable without making it a pointer, then you probably shouldn't declare it as a pointer.



        Very often programmers use pointers when they don't need to. At the time, they aren't thinking of any other way. In my experience, when it's brought to their attention to not use a pointer, they will often say that it's impossible not to use a pointer. And when I prove them otherwise, they will usually backtrack and say that their code (which uses pointers) is more efficient than the code that doesn't use pointers.



        (That's not true for all programmers, though. Some will recognize the appeal and simplicity of replacing a pointer with a non-pointer, and gladly change their code.)



        I can't speak for all cases, of course, but C compilers these days are usually smart enough to compile both pointer code and non-pointer code to be practically identical in terms of efficiency. Not only that, but depending on the case, non-pointer code is often more efficient than code that uses pointers.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 4 at 21:08

























        answered Jan 3 at 20:32









        J-LJ-L

        44619




        44619























            0














            Doing char *str = "I am a string"; means declaring and initializing an array of char. There's no problem since you're giving all the content of the array in the declaration.



            Doing int *pt = 606; is the same as doing char *str = 'a'; there's a problem: you're not giving enough information while declaring your variable.



            You need to do int nb = 606; int *pt = &nb; this way you give you pointer the address of the variable. Or if you want: you pass the int as an array of int.






            share|improve this answer





















            • 1





              There are a number of inaccuracies in this posting nor does it really answer the OP's question.

              – Richard Chambers
              Jan 3 at 16:35
















            0














            Doing char *str = "I am a string"; means declaring and initializing an array of char. There's no problem since you're giving all the content of the array in the declaration.



            Doing int *pt = 606; is the same as doing char *str = 'a'; there's a problem: you're not giving enough information while declaring your variable.



            You need to do int nb = 606; int *pt = &nb; this way you give you pointer the address of the variable. Or if you want: you pass the int as an array of int.






            share|improve this answer





















            • 1





              There are a number of inaccuracies in this posting nor does it really answer the OP's question.

              – Richard Chambers
              Jan 3 at 16:35














            0












            0








            0







            Doing char *str = "I am a string"; means declaring and initializing an array of char. There's no problem since you're giving all the content of the array in the declaration.



            Doing int *pt = 606; is the same as doing char *str = 'a'; there's a problem: you're not giving enough information while declaring your variable.



            You need to do int nb = 606; int *pt = &nb; this way you give you pointer the address of the variable. Or if you want: you pass the int as an array of int.






            share|improve this answer















            Doing char *str = "I am a string"; means declaring and initializing an array of char. There's no problem since you're giving all the content of the array in the declaration.



            Doing int *pt = 606; is the same as doing char *str = 'a'; there's a problem: you're not giving enough information while declaring your variable.



            You need to do int nb = 606; int *pt = &nb; this way you give you pointer the address of the variable. Or if you want: you pass the int as an array of int.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jan 4 at 12:43









            Vivit

            1,01111633




            1,01111633










            answered Jan 3 at 16:25









            Mathieu GasciolliMathieu Gasciolli

            114




            114








            • 1





              There are a number of inaccuracies in this posting nor does it really answer the OP's question.

              – Richard Chambers
              Jan 3 at 16:35














            • 1





              There are a number of inaccuracies in this posting nor does it really answer the OP's question.

              – Richard Chambers
              Jan 3 at 16:35








            1




            1





            There are a number of inaccuracies in this posting nor does it really answer the OP's question.

            – Richard Chambers
            Jan 3 at 16:35





            There are a number of inaccuracies in this posting nor does it really answer the OP's question.

            – Richard Chambers
            Jan 3 at 16:35


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54025987%2fpointers-and-access-to-memory-in-c-be-careful%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Human spaceflight

            Can not write log (Is /dev/pts mounted?) - openpty in Ubuntu-on-Windows?

            張江高科駅