C null terminator's throught char* correct handelling











up vote
2
down vote

favorite












This question is aimed at improving my understanding of

what I can and cannot do with pointers when allocating and freeing:



The bellow code is not meant to run, but just set up a situation for the questions bellow.



char *var1  = calloc(8,sizeof(char));
char **var2 = calloc(3,sizeof(char*));

var1 = "01234567";

var1[2] = '';
var1[5] = '';

//var1 = [0][1][][3][4][][6][7]

var2[0] = var1[0];
var2[1] = var1[3];
var2[2] = var1[6];

free(var1);
free(var2);


given the following snippet



1: is it ok to write to a location after the if you know the size you allocated.



2: Can I do what I did with var2 , if it points to a block that another pointer is pointing at?



3: are the calls to free ok? or will free die due to the located throughout var1.

I printed out all the variables after free, and only the ones up to the first null got freed (changed to null or other weird and normal looking characters). Is that ok?



4: Any other stuff you wish to point out that is completely wrong and should be avoided.



Thank you very much.










share|improve this question






















  • var1 = "01234567"; points var1 to a string literal (it does not copy the string into the allocated space). Maybe you meant strcpy here? Or are you really asking about that code? It would improve the question to post the exact code you are asking about, not "code not meant to run".
    – M.M
    Nov 19 at 23:04












  • i'll edit the question
    – Octavio del Ser
    Nov 19 at 23:10












  • Please do not invalidate existing answers by changing the question. Ask a new one instead.
    – n.m.
    Nov 19 at 23:13






  • 1




    It would probably be better to delete this question and post a new one, since there have already been answers posted. Check that the code you are asking about compiles before posting it, as you can see from this example the detail of the code is important
    – M.M
    Nov 19 at 23:15















up vote
2
down vote

favorite












This question is aimed at improving my understanding of

what I can and cannot do with pointers when allocating and freeing:



The bellow code is not meant to run, but just set up a situation for the questions bellow.



char *var1  = calloc(8,sizeof(char));
char **var2 = calloc(3,sizeof(char*));

var1 = "01234567";

var1[2] = '';
var1[5] = '';

//var1 = [0][1][][3][4][][6][7]

var2[0] = var1[0];
var2[1] = var1[3];
var2[2] = var1[6];

free(var1);
free(var2);


given the following snippet



1: is it ok to write to a location after the if you know the size you allocated.



2: Can I do what I did with var2 , if it points to a block that another pointer is pointing at?



3: are the calls to free ok? or will free die due to the located throughout var1.

I printed out all the variables after free, and only the ones up to the first null got freed (changed to null or other weird and normal looking characters). Is that ok?



4: Any other stuff you wish to point out that is completely wrong and should be avoided.



Thank you very much.










share|improve this question






















  • var1 = "01234567"; points var1 to a string literal (it does not copy the string into the allocated space). Maybe you meant strcpy here? Or are you really asking about that code? It would improve the question to post the exact code you are asking about, not "code not meant to run".
    – M.M
    Nov 19 at 23:04












  • i'll edit the question
    – Octavio del Ser
    Nov 19 at 23:10












  • Please do not invalidate existing answers by changing the question. Ask a new one instead.
    – n.m.
    Nov 19 at 23:13






  • 1




    It would probably be better to delete this question and post a new one, since there have already been answers posted. Check that the code you are asking about compiles before posting it, as you can see from this example the detail of the code is important
    – M.M
    Nov 19 at 23:15













up vote
2
down vote

favorite









up vote
2
down vote

favorite











This question is aimed at improving my understanding of

what I can and cannot do with pointers when allocating and freeing:



The bellow code is not meant to run, but just set up a situation for the questions bellow.



char *var1  = calloc(8,sizeof(char));
char **var2 = calloc(3,sizeof(char*));

var1 = "01234567";

var1[2] = '';
var1[5] = '';

//var1 = [0][1][][3][4][][6][7]

var2[0] = var1[0];
var2[1] = var1[3];
var2[2] = var1[6];

free(var1);
free(var2);


given the following snippet



1: is it ok to write to a location after the if you know the size you allocated.



2: Can I do what I did with var2 , if it points to a block that another pointer is pointing at?



3: are the calls to free ok? or will free die due to the located throughout var1.

I printed out all the variables after free, and only the ones up to the first null got freed (changed to null or other weird and normal looking characters). Is that ok?



4: Any other stuff you wish to point out that is completely wrong and should be avoided.



Thank you very much.










share|improve this question













This question is aimed at improving my understanding of

what I can and cannot do with pointers when allocating and freeing:



The bellow code is not meant to run, but just set up a situation for the questions bellow.



char *var1  = calloc(8,sizeof(char));
char **var2 = calloc(3,sizeof(char*));

var1 = "01234567";

var1[2] = '';
var1[5] = '';

//var1 = [0][1][][3][4][][6][7]

var2[0] = var1[0];
var2[1] = var1[3];
var2[2] = var1[6];

free(var1);
free(var2);


given the following snippet



1: is it ok to write to a location after the if you know the size you allocated.



2: Can I do what I did with var2 , if it points to a block that another pointer is pointing at?



3: are the calls to free ok? or will free die due to the located throughout var1.

I printed out all the variables after free, and only the ones up to the first null got freed (changed to null or other weird and normal looking characters). Is that ok?



4: Any other stuff you wish to point out that is completely wrong and should be avoided.



Thank you very much.







c memory-management memory-leaks






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 19 at 22:53









Octavio del Ser

235




235












  • var1 = "01234567"; points var1 to a string literal (it does not copy the string into the allocated space). Maybe you meant strcpy here? Or are you really asking about that code? It would improve the question to post the exact code you are asking about, not "code not meant to run".
    – M.M
    Nov 19 at 23:04












  • i'll edit the question
    – Octavio del Ser
    Nov 19 at 23:10












  • Please do not invalidate existing answers by changing the question. Ask a new one instead.
    – n.m.
    Nov 19 at 23:13






  • 1




    It would probably be better to delete this question and post a new one, since there have already been answers posted. Check that the code you are asking about compiles before posting it, as you can see from this example the detail of the code is important
    – M.M
    Nov 19 at 23:15


















  • var1 = "01234567"; points var1 to a string literal (it does not copy the string into the allocated space). Maybe you meant strcpy here? Or are you really asking about that code? It would improve the question to post the exact code you are asking about, not "code not meant to run".
    – M.M
    Nov 19 at 23:04












  • i'll edit the question
    – Octavio del Ser
    Nov 19 at 23:10












  • Please do not invalidate existing answers by changing the question. Ask a new one instead.
    – n.m.
    Nov 19 at 23:13






  • 1




    It would probably be better to delete this question and post a new one, since there have already been answers posted. Check that the code you are asking about compiles before posting it, as you can see from this example the detail of the code is important
    – M.M
    Nov 19 at 23:15
















var1 = "01234567"; points var1 to a string literal (it does not copy the string into the allocated space). Maybe you meant strcpy here? Or are you really asking about that code? It would improve the question to post the exact code you are asking about, not "code not meant to run".
– M.M
Nov 19 at 23:04






var1 = "01234567"; points var1 to a string literal (it does not copy the string into the allocated space). Maybe you meant strcpy here? Or are you really asking about that code? It would improve the question to post the exact code you are asking about, not "code not meant to run".
– M.M
Nov 19 at 23:04














i'll edit the question
– Octavio del Ser
Nov 19 at 23:10






i'll edit the question
– Octavio del Ser
Nov 19 at 23:10














Please do not invalidate existing answers by changing the question. Ask a new one instead.
– n.m.
Nov 19 at 23:13




Please do not invalidate existing answers by changing the question. Ask a new one instead.
– n.m.
Nov 19 at 23:13




1




1




It would probably be better to delete this question and post a new one, since there have already been answers posted. Check that the code you are asking about compiles before posting it, as you can see from this example the detail of the code is important
– M.M
Nov 19 at 23:15




It would probably be better to delete this question and post a new one, since there have already been answers posted. Check that the code you are asking about compiles before posting it, as you can see from this example the detail of the code is important
– M.M
Nov 19 at 23:15












4 Answers
4






active

oldest

votes

















up vote
1
down vote



accepted










Ok, let's just just recap what you have done here:



char *var1  = calloc(8,sizeof(char));
char **var2 = calloc(3,sizeof(char*));


So var1 is (a pointer to) a block of 8 chars, all set to zero .
And var2 is (a pointer to) a block of 3 pointers, all set to NULL.



So now it's the program's memory, it can do whatever it wants with it.



To answer your questions specifically ~



It's quite normal to write characters around inside your char block. It's a common programming pattern to parse string buffers by writing a after a section of text to use everyday C string operations on it, but then point to the next character after the added and continue parsing.



var2 is simply a bunch of char-pointers, it can point to whatever char is necessary, it doesn't necessarily have to be at the beginning of the string.



The calls to free() are somewhat OK (except for the bug - see below). It's normal for the content of free()d blocks to be overwritten when they are returned to the stack, so they often seem to have "rubbish" characters in them if printed out afterwards.



There is some issues with the assignment of var1 ~



var1 = "01234567";


Here you are saying "var1 now points to this constant string". Your compiler may have generated a warning about about this. Firstly the code assigns a const char* to a char* (hard-coded strings are const, but C compilers will only warn about this [EDIT: this is true for C++, not C, see comment from n.m.]). And secondly, the code lost all references to the block of memory that var1 used to point to. You can now never free() this memory - it has leaked. However, at the end of the program, the free() is trying to operate on a pointer-to a block of memory (the "01234567") which was not allocated on the heap. This is BAD. Since you're exiting immediately, there's no ill-effects, but if this was in the middle of execution, the next allocation (or next 1000th!) could crash weirdly. These sorts of problems are hard to debug.



Probably what you should have done here (I'm guessing your intention though) is used a string copy:



strncpy(var1, "01234567", 8);


With that operation instead of the assignment, everything is OK. This is because the digits are stored in the memory allocated on line1.






share|improve this answer



















  • 1




    In C, unlike in C++, string literals have type char[N] (but are not modifiable).
    – n.m.
    Nov 19 at 23:15










  • That's great thanks, could you follow up on: The calls to free() are somewhat OK (except for the bug - see below). what bugs, and how could I make them go away :D
    – Octavio del Ser
    Nov 19 at 23:18












  • @n.m. - Good point on the char[N], I've been doing too much C++ lately.
    – Kingsley
    Nov 19 at 23:27










  • @OctaviodelSer - the bug is the code is trying to free() that string "01234567" (line 4), which was not allocated from the heap. It's being free()d, because the code sets var1 to point to it (overwriting the address of the block you calloc()d on line 1). So in that one assignment, you leak the calloc()ed memory, and then (later) cause a false-free()
    – Kingsley
    Nov 19 at 23:33




















up vote
1
down vote













Question 4 - what's wrong



You 'calloc' some memory and store a pointer to it in var1. Then later you execute var1 = "01234567" which stores a pointer to a literal string in var1, thus losing the calloc'd memory. I imagine you thought you were copying a string. Use strcpy or similar.



Then you write zero values into what var1 points to. Since that's a literal string, it may fail if the literal is in read-only memory. The result is undefined.



free(var1) is not going to go well with a pointer to a literal. Your code may fail or you may get heap corruption.






share|improve this answer




























    up vote
    1
    down vote













    Pointers don't work this way.



    If someone wrote



    int a = 6*9;
    a = 42;


    you would wonder why they ever bothered to initialise a to 6*9 in the first place — and you would be right. There's no reason to. The value returned by * is simply forgotten without being used. It could be never calculated in the first place and no one would know the difference. This is exactly equivalent to



    int a = 42;


    Now when pointers are involved, there's some kind of evil neural pathway in our brain that tries to tell us that a sequence of statements that is exactly like the one shown above is somehow working differently. Don't trust your brain. It isn't.



    char *var1  = calloc(8,sizeof(char));
    var1 = "01234567";


    You would wonder why they ever bothered to initialise var1 to calloc(8,sizeof(char)); in the first place — and you would be right. There's no reason to. The value returned by calloc is simply forgotten without being used. It could be never calculated in the first place and no one would know the difference. This is exactly equivalent to



    char* var1 = "01234567";


    ... which is a problem, because you cannot modify string literals.



    What you probably want is



    char *var1  = calloc(8, 1);     // note sizeof(char)==1, always
    strncpy (var1, "01234567", 8); // note not strcpy — you would need 9 bytes for it


    or some variation of that.






    share|improve this answer






























      up vote
      0
      down vote













      var1 = "01234567"; is not correct because you assign a value of pointer to const char to a pointer to mutable char and causes a memory leak because the value of pointer to a calloc allocated buffer of 8 char stored in variable var1 is lost. It seems like you actually intended to initialize allocated array with the value of the string literal instead (though that would require allocation of an array of 9 items). Assignment var1[2] = ''; causes undefined behavior because the location var1 points to is not mutable. var2[0] = var1[0]; is wrong as well because you assign a value of char to pointer to char. Finally free(var1); will try to deallocate a pointer to buffer baking string literal, not something you allocated.






      share|improve this answer























      • "01234567" is an array of non-const char in C. "non-modifiable" would be a more accurate terminology
        – M.M
        Nov 19 at 23:11












      • @M.M since when string literals became arrays of non-const char?
        – VTT
        Nov 19 at 23:14










      • @VTT They never were anything else in C.
        – n.m.
        Nov 19 at 23:15










      • That has always been the case in C. When const was added to the language, they did not change string literals to be const because it would have invalidated all the pre-existing code that does char *a = "foo"; and so on
        – M.M
        Nov 19 at 23:15












      • @M.M it would be more accurate terminology if const was used for "non-modifiable" stuff. Note that they did invalidate all the pre-existing code that does char *a = "foo" anyway because some of that code modified array assuming that it was fine.
        – VTT
        Nov 19 at 23:21













      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',
      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%2f53383804%2fc-null-terminators-throught-char-correct-handelling%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      1
      down vote



      accepted










      Ok, let's just just recap what you have done here:



      char *var1  = calloc(8,sizeof(char));
      char **var2 = calloc(3,sizeof(char*));


      So var1 is (a pointer to) a block of 8 chars, all set to zero .
      And var2 is (a pointer to) a block of 3 pointers, all set to NULL.



      So now it's the program's memory, it can do whatever it wants with it.



      To answer your questions specifically ~



      It's quite normal to write characters around inside your char block. It's a common programming pattern to parse string buffers by writing a after a section of text to use everyday C string operations on it, but then point to the next character after the added and continue parsing.



      var2 is simply a bunch of char-pointers, it can point to whatever char is necessary, it doesn't necessarily have to be at the beginning of the string.



      The calls to free() are somewhat OK (except for the bug - see below). It's normal for the content of free()d blocks to be overwritten when they are returned to the stack, so they often seem to have "rubbish" characters in them if printed out afterwards.



      There is some issues with the assignment of var1 ~



      var1 = "01234567";


      Here you are saying "var1 now points to this constant string". Your compiler may have generated a warning about about this. Firstly the code assigns a const char* to a char* (hard-coded strings are const, but C compilers will only warn about this [EDIT: this is true for C++, not C, see comment from n.m.]). And secondly, the code lost all references to the block of memory that var1 used to point to. You can now never free() this memory - it has leaked. However, at the end of the program, the free() is trying to operate on a pointer-to a block of memory (the "01234567") which was not allocated on the heap. This is BAD. Since you're exiting immediately, there's no ill-effects, but if this was in the middle of execution, the next allocation (or next 1000th!) could crash weirdly. These sorts of problems are hard to debug.



      Probably what you should have done here (I'm guessing your intention though) is used a string copy:



      strncpy(var1, "01234567", 8);


      With that operation instead of the assignment, everything is OK. This is because the digits are stored in the memory allocated on line1.






      share|improve this answer



















      • 1




        In C, unlike in C++, string literals have type char[N] (but are not modifiable).
        – n.m.
        Nov 19 at 23:15










      • That's great thanks, could you follow up on: The calls to free() are somewhat OK (except for the bug - see below). what bugs, and how could I make them go away :D
        – Octavio del Ser
        Nov 19 at 23:18












      • @n.m. - Good point on the char[N], I've been doing too much C++ lately.
        – Kingsley
        Nov 19 at 23:27










      • @OctaviodelSer - the bug is the code is trying to free() that string "01234567" (line 4), which was not allocated from the heap. It's being free()d, because the code sets var1 to point to it (overwriting the address of the block you calloc()d on line 1). So in that one assignment, you leak the calloc()ed memory, and then (later) cause a false-free()
        – Kingsley
        Nov 19 at 23:33

















      up vote
      1
      down vote



      accepted










      Ok, let's just just recap what you have done here:



      char *var1  = calloc(8,sizeof(char));
      char **var2 = calloc(3,sizeof(char*));


      So var1 is (a pointer to) a block of 8 chars, all set to zero .
      And var2 is (a pointer to) a block of 3 pointers, all set to NULL.



      So now it's the program's memory, it can do whatever it wants with it.



      To answer your questions specifically ~



      It's quite normal to write characters around inside your char block. It's a common programming pattern to parse string buffers by writing a after a section of text to use everyday C string operations on it, but then point to the next character after the added and continue parsing.



      var2 is simply a bunch of char-pointers, it can point to whatever char is necessary, it doesn't necessarily have to be at the beginning of the string.



      The calls to free() are somewhat OK (except for the bug - see below). It's normal for the content of free()d blocks to be overwritten when they are returned to the stack, so they often seem to have "rubbish" characters in them if printed out afterwards.



      There is some issues with the assignment of var1 ~



      var1 = "01234567";


      Here you are saying "var1 now points to this constant string". Your compiler may have generated a warning about about this. Firstly the code assigns a const char* to a char* (hard-coded strings are const, but C compilers will only warn about this [EDIT: this is true for C++, not C, see comment from n.m.]). And secondly, the code lost all references to the block of memory that var1 used to point to. You can now never free() this memory - it has leaked. However, at the end of the program, the free() is trying to operate on a pointer-to a block of memory (the "01234567") which was not allocated on the heap. This is BAD. Since you're exiting immediately, there's no ill-effects, but if this was in the middle of execution, the next allocation (or next 1000th!) could crash weirdly. These sorts of problems are hard to debug.



      Probably what you should have done here (I'm guessing your intention though) is used a string copy:



      strncpy(var1, "01234567", 8);


      With that operation instead of the assignment, everything is OK. This is because the digits are stored in the memory allocated on line1.






      share|improve this answer



















      • 1




        In C, unlike in C++, string literals have type char[N] (but are not modifiable).
        – n.m.
        Nov 19 at 23:15










      • That's great thanks, could you follow up on: The calls to free() are somewhat OK (except for the bug - see below). what bugs, and how could I make them go away :D
        – Octavio del Ser
        Nov 19 at 23:18












      • @n.m. - Good point on the char[N], I've been doing too much C++ lately.
        – Kingsley
        Nov 19 at 23:27










      • @OctaviodelSer - the bug is the code is trying to free() that string "01234567" (line 4), which was not allocated from the heap. It's being free()d, because the code sets var1 to point to it (overwriting the address of the block you calloc()d on line 1). So in that one assignment, you leak the calloc()ed memory, and then (later) cause a false-free()
        – Kingsley
        Nov 19 at 23:33















      up vote
      1
      down vote



      accepted







      up vote
      1
      down vote



      accepted






      Ok, let's just just recap what you have done here:



      char *var1  = calloc(8,sizeof(char));
      char **var2 = calloc(3,sizeof(char*));


      So var1 is (a pointer to) a block of 8 chars, all set to zero .
      And var2 is (a pointer to) a block of 3 pointers, all set to NULL.



      So now it's the program's memory, it can do whatever it wants with it.



      To answer your questions specifically ~



      It's quite normal to write characters around inside your char block. It's a common programming pattern to parse string buffers by writing a after a section of text to use everyday C string operations on it, but then point to the next character after the added and continue parsing.



      var2 is simply a bunch of char-pointers, it can point to whatever char is necessary, it doesn't necessarily have to be at the beginning of the string.



      The calls to free() are somewhat OK (except for the bug - see below). It's normal for the content of free()d blocks to be overwritten when they are returned to the stack, so they often seem to have "rubbish" characters in them if printed out afterwards.



      There is some issues with the assignment of var1 ~



      var1 = "01234567";


      Here you are saying "var1 now points to this constant string". Your compiler may have generated a warning about about this. Firstly the code assigns a const char* to a char* (hard-coded strings are const, but C compilers will only warn about this [EDIT: this is true for C++, not C, see comment from n.m.]). And secondly, the code lost all references to the block of memory that var1 used to point to. You can now never free() this memory - it has leaked. However, at the end of the program, the free() is trying to operate on a pointer-to a block of memory (the "01234567") which was not allocated on the heap. This is BAD. Since you're exiting immediately, there's no ill-effects, but if this was in the middle of execution, the next allocation (or next 1000th!) could crash weirdly. These sorts of problems are hard to debug.



      Probably what you should have done here (I'm guessing your intention though) is used a string copy:



      strncpy(var1, "01234567", 8);


      With that operation instead of the assignment, everything is OK. This is because the digits are stored in the memory allocated on line1.






      share|improve this answer














      Ok, let's just just recap what you have done here:



      char *var1  = calloc(8,sizeof(char));
      char **var2 = calloc(3,sizeof(char*));


      So var1 is (a pointer to) a block of 8 chars, all set to zero .
      And var2 is (a pointer to) a block of 3 pointers, all set to NULL.



      So now it's the program's memory, it can do whatever it wants with it.



      To answer your questions specifically ~



      It's quite normal to write characters around inside your char block. It's a common programming pattern to parse string buffers by writing a after a section of text to use everyday C string operations on it, but then point to the next character after the added and continue parsing.



      var2 is simply a bunch of char-pointers, it can point to whatever char is necessary, it doesn't necessarily have to be at the beginning of the string.



      The calls to free() are somewhat OK (except for the bug - see below). It's normal for the content of free()d blocks to be overwritten when they are returned to the stack, so they often seem to have "rubbish" characters in them if printed out afterwards.



      There is some issues with the assignment of var1 ~



      var1 = "01234567";


      Here you are saying "var1 now points to this constant string". Your compiler may have generated a warning about about this. Firstly the code assigns a const char* to a char* (hard-coded strings are const, but C compilers will only warn about this [EDIT: this is true for C++, not C, see comment from n.m.]). And secondly, the code lost all references to the block of memory that var1 used to point to. You can now never free() this memory - it has leaked. However, at the end of the program, the free() is trying to operate on a pointer-to a block of memory (the "01234567") which was not allocated on the heap. This is BAD. Since you're exiting immediately, there's no ill-effects, but if this was in the middle of execution, the next allocation (or next 1000th!) could crash weirdly. These sorts of problems are hard to debug.



      Probably what you should have done here (I'm guessing your intention though) is used a string copy:



      strncpy(var1, "01234567", 8);


      With that operation instead of the assignment, everything is OK. This is because the digits are stored in the memory allocated on line1.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 19 at 23:40

























      answered Nov 19 at 23:13









      Kingsley

      1,7961918




      1,7961918








      • 1




        In C, unlike in C++, string literals have type char[N] (but are not modifiable).
        – n.m.
        Nov 19 at 23:15










      • That's great thanks, could you follow up on: The calls to free() are somewhat OK (except for the bug - see below). what bugs, and how could I make them go away :D
        – Octavio del Ser
        Nov 19 at 23:18












      • @n.m. - Good point on the char[N], I've been doing too much C++ lately.
        – Kingsley
        Nov 19 at 23:27










      • @OctaviodelSer - the bug is the code is trying to free() that string "01234567" (line 4), which was not allocated from the heap. It's being free()d, because the code sets var1 to point to it (overwriting the address of the block you calloc()d on line 1). So in that one assignment, you leak the calloc()ed memory, and then (later) cause a false-free()
        – Kingsley
        Nov 19 at 23:33
















      • 1




        In C, unlike in C++, string literals have type char[N] (but are not modifiable).
        – n.m.
        Nov 19 at 23:15










      • That's great thanks, could you follow up on: The calls to free() are somewhat OK (except for the bug - see below). what bugs, and how could I make them go away :D
        – Octavio del Ser
        Nov 19 at 23:18












      • @n.m. - Good point on the char[N], I've been doing too much C++ lately.
        – Kingsley
        Nov 19 at 23:27










      • @OctaviodelSer - the bug is the code is trying to free() that string "01234567" (line 4), which was not allocated from the heap. It's being free()d, because the code sets var1 to point to it (overwriting the address of the block you calloc()d on line 1). So in that one assignment, you leak the calloc()ed memory, and then (later) cause a false-free()
        – Kingsley
        Nov 19 at 23:33










      1




      1




      In C, unlike in C++, string literals have type char[N] (but are not modifiable).
      – n.m.
      Nov 19 at 23:15




      In C, unlike in C++, string literals have type char[N] (but are not modifiable).
      – n.m.
      Nov 19 at 23:15












      That's great thanks, could you follow up on: The calls to free() are somewhat OK (except for the bug - see below). what bugs, and how could I make them go away :D
      – Octavio del Ser
      Nov 19 at 23:18






      That's great thanks, could you follow up on: The calls to free() are somewhat OK (except for the bug - see below). what bugs, and how could I make them go away :D
      – Octavio del Ser
      Nov 19 at 23:18














      @n.m. - Good point on the char[N], I've been doing too much C++ lately.
      – Kingsley
      Nov 19 at 23:27




      @n.m. - Good point on the char[N], I've been doing too much C++ lately.
      – Kingsley
      Nov 19 at 23:27












      @OctaviodelSer - the bug is the code is trying to free() that string "01234567" (line 4), which was not allocated from the heap. It's being free()d, because the code sets var1 to point to it (overwriting the address of the block you calloc()d on line 1). So in that one assignment, you leak the calloc()ed memory, and then (later) cause a false-free()
      – Kingsley
      Nov 19 at 23:33






      @OctaviodelSer - the bug is the code is trying to free() that string "01234567" (line 4), which was not allocated from the heap. It's being free()d, because the code sets var1 to point to it (overwriting the address of the block you calloc()d on line 1). So in that one assignment, you leak the calloc()ed memory, and then (later) cause a false-free()
      – Kingsley
      Nov 19 at 23:33














      up vote
      1
      down vote













      Question 4 - what's wrong



      You 'calloc' some memory and store a pointer to it in var1. Then later you execute var1 = "01234567" which stores a pointer to a literal string in var1, thus losing the calloc'd memory. I imagine you thought you were copying a string. Use strcpy or similar.



      Then you write zero values into what var1 points to. Since that's a literal string, it may fail if the literal is in read-only memory. The result is undefined.



      free(var1) is not going to go well with a pointer to a literal. Your code may fail or you may get heap corruption.






      share|improve this answer

























        up vote
        1
        down vote













        Question 4 - what's wrong



        You 'calloc' some memory and store a pointer to it in var1. Then later you execute var1 = "01234567" which stores a pointer to a literal string in var1, thus losing the calloc'd memory. I imagine you thought you were copying a string. Use strcpy or similar.



        Then you write zero values into what var1 points to. Since that's a literal string, it may fail if the literal is in read-only memory. The result is undefined.



        free(var1) is not going to go well with a pointer to a literal. Your code may fail or you may get heap corruption.






        share|improve this answer























          up vote
          1
          down vote










          up vote
          1
          down vote









          Question 4 - what's wrong



          You 'calloc' some memory and store a pointer to it in var1. Then later you execute var1 = "01234567" which stores a pointer to a literal string in var1, thus losing the calloc'd memory. I imagine you thought you were copying a string. Use strcpy or similar.



          Then you write zero values into what var1 points to. Since that's a literal string, it may fail if the literal is in read-only memory. The result is undefined.



          free(var1) is not going to go well with a pointer to a literal. Your code may fail or you may get heap corruption.






          share|improve this answer












          Question 4 - what's wrong



          You 'calloc' some memory and store a pointer to it in var1. Then later you execute var1 = "01234567" which stores a pointer to a literal string in var1, thus losing the calloc'd memory. I imagine you thought you were copying a string. Use strcpy or similar.



          Then you write zero values into what var1 points to. Since that's a literal string, it may fail if the literal is in read-only memory. The result is undefined.



          free(var1) is not going to go well with a pointer to a literal. Your code may fail or you may get heap corruption.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 19 at 23:05









          dave

          111




          111






















              up vote
              1
              down vote













              Pointers don't work this way.



              If someone wrote



              int a = 6*9;
              a = 42;


              you would wonder why they ever bothered to initialise a to 6*9 in the first place — and you would be right. There's no reason to. The value returned by * is simply forgotten without being used. It could be never calculated in the first place and no one would know the difference. This is exactly equivalent to



              int a = 42;


              Now when pointers are involved, there's some kind of evil neural pathway in our brain that tries to tell us that a sequence of statements that is exactly like the one shown above is somehow working differently. Don't trust your brain. It isn't.



              char *var1  = calloc(8,sizeof(char));
              var1 = "01234567";


              You would wonder why they ever bothered to initialise var1 to calloc(8,sizeof(char)); in the first place — and you would be right. There's no reason to. The value returned by calloc is simply forgotten without being used. It could be never calculated in the first place and no one would know the difference. This is exactly equivalent to



              char* var1 = "01234567";


              ... which is a problem, because you cannot modify string literals.



              What you probably want is



              char *var1  = calloc(8, 1);     // note sizeof(char)==1, always
              strncpy (var1, "01234567", 8); // note not strcpy — you would need 9 bytes for it


              or some variation of that.






              share|improve this answer



























                up vote
                1
                down vote













                Pointers don't work this way.



                If someone wrote



                int a = 6*9;
                a = 42;


                you would wonder why they ever bothered to initialise a to 6*9 in the first place — and you would be right. There's no reason to. The value returned by * is simply forgotten without being used. It could be never calculated in the first place and no one would know the difference. This is exactly equivalent to



                int a = 42;


                Now when pointers are involved, there's some kind of evil neural pathway in our brain that tries to tell us that a sequence of statements that is exactly like the one shown above is somehow working differently. Don't trust your brain. It isn't.



                char *var1  = calloc(8,sizeof(char));
                var1 = "01234567";


                You would wonder why they ever bothered to initialise var1 to calloc(8,sizeof(char)); in the first place — and you would be right. There's no reason to. The value returned by calloc is simply forgotten without being used. It could be never calculated in the first place and no one would know the difference. This is exactly equivalent to



                char* var1 = "01234567";


                ... which is a problem, because you cannot modify string literals.



                What you probably want is



                char *var1  = calloc(8, 1);     // note sizeof(char)==1, always
                strncpy (var1, "01234567", 8); // note not strcpy — you would need 9 bytes for it


                or some variation of that.






                share|improve this answer

























                  up vote
                  1
                  down vote










                  up vote
                  1
                  down vote









                  Pointers don't work this way.



                  If someone wrote



                  int a = 6*9;
                  a = 42;


                  you would wonder why they ever bothered to initialise a to 6*9 in the first place — and you would be right. There's no reason to. The value returned by * is simply forgotten without being used. It could be never calculated in the first place and no one would know the difference. This is exactly equivalent to



                  int a = 42;


                  Now when pointers are involved, there's some kind of evil neural pathway in our brain that tries to tell us that a sequence of statements that is exactly like the one shown above is somehow working differently. Don't trust your brain. It isn't.



                  char *var1  = calloc(8,sizeof(char));
                  var1 = "01234567";


                  You would wonder why they ever bothered to initialise var1 to calloc(8,sizeof(char)); in the first place — and you would be right. There's no reason to. The value returned by calloc is simply forgotten without being used. It could be never calculated in the first place and no one would know the difference. This is exactly equivalent to



                  char* var1 = "01234567";


                  ... which is a problem, because you cannot modify string literals.



                  What you probably want is



                  char *var1  = calloc(8, 1);     // note sizeof(char)==1, always
                  strncpy (var1, "01234567", 8); // note not strcpy — you would need 9 bytes for it


                  or some variation of that.






                  share|improve this answer














                  Pointers don't work this way.



                  If someone wrote



                  int a = 6*9;
                  a = 42;


                  you would wonder why they ever bothered to initialise a to 6*9 in the first place — and you would be right. There's no reason to. The value returned by * is simply forgotten without being used. It could be never calculated in the first place and no one would know the difference. This is exactly equivalent to



                  int a = 42;


                  Now when pointers are involved, there's some kind of evil neural pathway in our brain that tries to tell us that a sequence of statements that is exactly like the one shown above is somehow working differently. Don't trust your brain. It isn't.



                  char *var1  = calloc(8,sizeof(char));
                  var1 = "01234567";


                  You would wonder why they ever bothered to initialise var1 to calloc(8,sizeof(char)); in the first place — and you would be right. There's no reason to. The value returned by calloc is simply forgotten without being used. It could be never calculated in the first place and no one would know the difference. This is exactly equivalent to



                  char* var1 = "01234567";


                  ... which is a problem, because you cannot modify string literals.



                  What you probably want is



                  char *var1  = calloc(8, 1);     // note sizeof(char)==1, always
                  strncpy (var1, "01234567", 8); // note not strcpy — you would need 9 bytes for it


                  or some variation of that.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 19 at 23:20

























                  answered Nov 19 at 23:07









                  n.m.

                  70.4k882165




                  70.4k882165






















                      up vote
                      0
                      down vote













                      var1 = "01234567"; is not correct because you assign a value of pointer to const char to a pointer to mutable char and causes a memory leak because the value of pointer to a calloc allocated buffer of 8 char stored in variable var1 is lost. It seems like you actually intended to initialize allocated array with the value of the string literal instead (though that would require allocation of an array of 9 items). Assignment var1[2] = ''; causes undefined behavior because the location var1 points to is not mutable. var2[0] = var1[0]; is wrong as well because you assign a value of char to pointer to char. Finally free(var1); will try to deallocate a pointer to buffer baking string literal, not something you allocated.






                      share|improve this answer























                      • "01234567" is an array of non-const char in C. "non-modifiable" would be a more accurate terminology
                        – M.M
                        Nov 19 at 23:11












                      • @M.M since when string literals became arrays of non-const char?
                        – VTT
                        Nov 19 at 23:14










                      • @VTT They never were anything else in C.
                        – n.m.
                        Nov 19 at 23:15










                      • That has always been the case in C. When const was added to the language, they did not change string literals to be const because it would have invalidated all the pre-existing code that does char *a = "foo"; and so on
                        – M.M
                        Nov 19 at 23:15












                      • @M.M it would be more accurate terminology if const was used for "non-modifiable" stuff. Note that they did invalidate all the pre-existing code that does char *a = "foo" anyway because some of that code modified array assuming that it was fine.
                        – VTT
                        Nov 19 at 23:21

















                      up vote
                      0
                      down vote













                      var1 = "01234567"; is not correct because you assign a value of pointer to const char to a pointer to mutable char and causes a memory leak because the value of pointer to a calloc allocated buffer of 8 char stored in variable var1 is lost. It seems like you actually intended to initialize allocated array with the value of the string literal instead (though that would require allocation of an array of 9 items). Assignment var1[2] = ''; causes undefined behavior because the location var1 points to is not mutable. var2[0] = var1[0]; is wrong as well because you assign a value of char to pointer to char. Finally free(var1); will try to deallocate a pointer to buffer baking string literal, not something you allocated.






                      share|improve this answer























                      • "01234567" is an array of non-const char in C. "non-modifiable" would be a more accurate terminology
                        – M.M
                        Nov 19 at 23:11












                      • @M.M since when string literals became arrays of non-const char?
                        – VTT
                        Nov 19 at 23:14










                      • @VTT They never were anything else in C.
                        – n.m.
                        Nov 19 at 23:15










                      • That has always been the case in C. When const was added to the language, they did not change string literals to be const because it would have invalidated all the pre-existing code that does char *a = "foo"; and so on
                        – M.M
                        Nov 19 at 23:15












                      • @M.M it would be more accurate terminology if const was used for "non-modifiable" stuff. Note that they did invalidate all the pre-existing code that does char *a = "foo" anyway because some of that code modified array assuming that it was fine.
                        – VTT
                        Nov 19 at 23:21















                      up vote
                      0
                      down vote










                      up vote
                      0
                      down vote









                      var1 = "01234567"; is not correct because you assign a value of pointer to const char to a pointer to mutable char and causes a memory leak because the value of pointer to a calloc allocated buffer of 8 char stored in variable var1 is lost. It seems like you actually intended to initialize allocated array with the value of the string literal instead (though that would require allocation of an array of 9 items). Assignment var1[2] = ''; causes undefined behavior because the location var1 points to is not mutable. var2[0] = var1[0]; is wrong as well because you assign a value of char to pointer to char. Finally free(var1); will try to deallocate a pointer to buffer baking string literal, not something you allocated.






                      share|improve this answer














                      var1 = "01234567"; is not correct because you assign a value of pointer to const char to a pointer to mutable char and causes a memory leak because the value of pointer to a calloc allocated buffer of 8 char stored in variable var1 is lost. It seems like you actually intended to initialize allocated array with the value of the string literal instead (though that would require allocation of an array of 9 items). Assignment var1[2] = ''; causes undefined behavior because the location var1 points to is not mutable. var2[0] = var1[0]; is wrong as well because you assign a value of char to pointer to char. Finally free(var1); will try to deallocate a pointer to buffer baking string literal, not something you allocated.







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Nov 19 at 23:26

























                      answered Nov 19 at 23:09









                      VTT

                      23.4k42345




                      23.4k42345












                      • "01234567" is an array of non-const char in C. "non-modifiable" would be a more accurate terminology
                        – M.M
                        Nov 19 at 23:11












                      • @M.M since when string literals became arrays of non-const char?
                        – VTT
                        Nov 19 at 23:14










                      • @VTT They never were anything else in C.
                        – n.m.
                        Nov 19 at 23:15










                      • That has always been the case in C. When const was added to the language, they did not change string literals to be const because it would have invalidated all the pre-existing code that does char *a = "foo"; and so on
                        – M.M
                        Nov 19 at 23:15












                      • @M.M it would be more accurate terminology if const was used for "non-modifiable" stuff. Note that they did invalidate all the pre-existing code that does char *a = "foo" anyway because some of that code modified array assuming that it was fine.
                        – VTT
                        Nov 19 at 23:21




















                      • "01234567" is an array of non-const char in C. "non-modifiable" would be a more accurate terminology
                        – M.M
                        Nov 19 at 23:11












                      • @M.M since when string literals became arrays of non-const char?
                        – VTT
                        Nov 19 at 23:14










                      • @VTT They never were anything else in C.
                        – n.m.
                        Nov 19 at 23:15










                      • That has always been the case in C. When const was added to the language, they did not change string literals to be const because it would have invalidated all the pre-existing code that does char *a = "foo"; and so on
                        – M.M
                        Nov 19 at 23:15












                      • @M.M it would be more accurate terminology if const was used for "non-modifiable" stuff. Note that they did invalidate all the pre-existing code that does char *a = "foo" anyway because some of that code modified array assuming that it was fine.
                        – VTT
                        Nov 19 at 23:21


















                      "01234567" is an array of non-const char in C. "non-modifiable" would be a more accurate terminology
                      – M.M
                      Nov 19 at 23:11






                      "01234567" is an array of non-const char in C. "non-modifiable" would be a more accurate terminology
                      – M.M
                      Nov 19 at 23:11














                      @M.M since when string literals became arrays of non-const char?
                      – VTT
                      Nov 19 at 23:14




                      @M.M since when string literals became arrays of non-const char?
                      – VTT
                      Nov 19 at 23:14












                      @VTT They never were anything else in C.
                      – n.m.
                      Nov 19 at 23:15




                      @VTT They never were anything else in C.
                      – n.m.
                      Nov 19 at 23:15












                      That has always been the case in C. When const was added to the language, they did not change string literals to be const because it would have invalidated all the pre-existing code that does char *a = "foo"; and so on
                      – M.M
                      Nov 19 at 23:15






                      That has always been the case in C. When const was added to the language, they did not change string literals to be const because it would have invalidated all the pre-existing code that does char *a = "foo"; and so on
                      – M.M
                      Nov 19 at 23:15














                      @M.M it would be more accurate terminology if const was used for "non-modifiable" stuff. Note that they did invalidate all the pre-existing code that does char *a = "foo" anyway because some of that code modified array assuming that it was fine.
                      – VTT
                      Nov 19 at 23:21






                      @M.M it would be more accurate terminology if const was used for "non-modifiable" stuff. Note that they did invalidate all the pre-existing code that does char *a = "foo" anyway because some of that code modified array assuming that it was fine.
                      – VTT
                      Nov 19 at 23:21




















                      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.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • 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%2f53383804%2fc-null-terminators-throught-char-correct-handelling%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

                      Wiesbaden

                      Marschland

                      Dieringhausen