Where the following objects are stored in memory?












0















#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define TEXT "Good luck on this test"
int main () {
char* cPtr = (char*)malloc(sizeof(TEXT));
strncpy(cPtr,TEXT,sizeof(TEXT));
printf("%sn",cPtr);
free(cPtr);
return(EXIT_SUCCESS);
}



  1. The memory for variable cPtr?

  2. The address to which cPtr points?

  3. The code for malloc()?

  4. The code that malloc() calls to move the brk pointer for the
    process running this program?


I think its:




  1. Heap

  2. Stack

  3. Data segment

  4. Shared library memory


Is it correct?










share|improve this question

























  • I don't believe 3. is correct. The TEXT macro would be stored in the data segment though.

    – Patrick Roberts
    Nov 19 '18 at 23:24






  • 1





    Some systems don't have a heap or a stack

    – M.M
    Nov 19 '18 at 23:25






  • 1





    An answer to this question would be platform specific.

    – VTT
    Nov 19 '18 at 23:29






  • 2





    I think 1 and 2 are backwards. char *cPtr is on the stack. "The address to which cPtr points" sounds like they're asking about the memory allocated by malloc; that's on the heap.

    – Schwern
    Nov 19 '18 at 23:30






  • 1





    Nothing in the C/C++ standard mandates that anything must end on the stack, or even that the thing known as “stack” exists. You need to look in the assembly output to see what happens, as all of it is implementation-defined. I.e. the question should also state what exact compiler is spoken about, and what compiler options.

    – Kuba Ober
    Nov 20 '18 at 3:04
















0















#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define TEXT "Good luck on this test"
int main () {
char* cPtr = (char*)malloc(sizeof(TEXT));
strncpy(cPtr,TEXT,sizeof(TEXT));
printf("%sn",cPtr);
free(cPtr);
return(EXIT_SUCCESS);
}



  1. The memory for variable cPtr?

  2. The address to which cPtr points?

  3. The code for malloc()?

  4. The code that malloc() calls to move the brk pointer for the
    process running this program?


I think its:




  1. Heap

  2. Stack

  3. Data segment

  4. Shared library memory


Is it correct?










share|improve this question

























  • I don't believe 3. is correct. The TEXT macro would be stored in the data segment though.

    – Patrick Roberts
    Nov 19 '18 at 23:24






  • 1





    Some systems don't have a heap or a stack

    – M.M
    Nov 19 '18 at 23:25






  • 1





    An answer to this question would be platform specific.

    – VTT
    Nov 19 '18 at 23:29






  • 2





    I think 1 and 2 are backwards. char *cPtr is on the stack. "The address to which cPtr points" sounds like they're asking about the memory allocated by malloc; that's on the heap.

    – Schwern
    Nov 19 '18 at 23:30






  • 1





    Nothing in the C/C++ standard mandates that anything must end on the stack, or even that the thing known as “stack” exists. You need to look in the assembly output to see what happens, as all of it is implementation-defined. I.e. the question should also state what exact compiler is spoken about, and what compiler options.

    – Kuba Ober
    Nov 20 '18 at 3:04














0












0








0


1






#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define TEXT "Good luck on this test"
int main () {
char* cPtr = (char*)malloc(sizeof(TEXT));
strncpy(cPtr,TEXT,sizeof(TEXT));
printf("%sn",cPtr);
free(cPtr);
return(EXIT_SUCCESS);
}



  1. The memory for variable cPtr?

  2. The address to which cPtr points?

  3. The code for malloc()?

  4. The code that malloc() calls to move the brk pointer for the
    process running this program?


I think its:




  1. Heap

  2. Stack

  3. Data segment

  4. Shared library memory


Is it correct?










share|improve this question
















#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define TEXT "Good luck on this test"
int main () {
char* cPtr = (char*)malloc(sizeof(TEXT));
strncpy(cPtr,TEXT,sizeof(TEXT));
printf("%sn",cPtr);
free(cPtr);
return(EXIT_SUCCESS);
}



  1. The memory for variable cPtr?

  2. The address to which cPtr points?

  3. The code for malloc()?

  4. The code that malloc() calls to move the brk pointer for the
    process running this program?


I think its:




  1. Heap

  2. Stack

  3. Data segment

  4. Shared library memory


Is it correct?







c






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 19 '18 at 23:56









Dennis Vash

571316




571316










asked Nov 19 '18 at 23:21









Harold LHarold L

32




32













  • I don't believe 3. is correct. The TEXT macro would be stored in the data segment though.

    – Patrick Roberts
    Nov 19 '18 at 23:24






  • 1





    Some systems don't have a heap or a stack

    – M.M
    Nov 19 '18 at 23:25






  • 1





    An answer to this question would be platform specific.

    – VTT
    Nov 19 '18 at 23:29






  • 2





    I think 1 and 2 are backwards. char *cPtr is on the stack. "The address to which cPtr points" sounds like they're asking about the memory allocated by malloc; that's on the heap.

    – Schwern
    Nov 19 '18 at 23:30






  • 1





    Nothing in the C/C++ standard mandates that anything must end on the stack, or even that the thing known as “stack” exists. You need to look in the assembly output to see what happens, as all of it is implementation-defined. I.e. the question should also state what exact compiler is spoken about, and what compiler options.

    – Kuba Ober
    Nov 20 '18 at 3:04



















  • I don't believe 3. is correct. The TEXT macro would be stored in the data segment though.

    – Patrick Roberts
    Nov 19 '18 at 23:24






  • 1





    Some systems don't have a heap or a stack

    – M.M
    Nov 19 '18 at 23:25






  • 1





    An answer to this question would be platform specific.

    – VTT
    Nov 19 '18 at 23:29






  • 2





    I think 1 and 2 are backwards. char *cPtr is on the stack. "The address to which cPtr points" sounds like they're asking about the memory allocated by malloc; that's on the heap.

    – Schwern
    Nov 19 '18 at 23:30






  • 1





    Nothing in the C/C++ standard mandates that anything must end on the stack, or even that the thing known as “stack” exists. You need to look in the assembly output to see what happens, as all of it is implementation-defined. I.e. the question should also state what exact compiler is spoken about, and what compiler options.

    – Kuba Ober
    Nov 20 '18 at 3:04

















I don't believe 3. is correct. The TEXT macro would be stored in the data segment though.

– Patrick Roberts
Nov 19 '18 at 23:24





I don't believe 3. is correct. The TEXT macro would be stored in the data segment though.

– Patrick Roberts
Nov 19 '18 at 23:24




1




1





Some systems don't have a heap or a stack

– M.M
Nov 19 '18 at 23:25





Some systems don't have a heap or a stack

– M.M
Nov 19 '18 at 23:25




1




1





An answer to this question would be platform specific.

– VTT
Nov 19 '18 at 23:29





An answer to this question would be platform specific.

– VTT
Nov 19 '18 at 23:29




2




2





I think 1 and 2 are backwards. char *cPtr is on the stack. "The address to which cPtr points" sounds like they're asking about the memory allocated by malloc; that's on the heap.

– Schwern
Nov 19 '18 at 23:30





I think 1 and 2 are backwards. char *cPtr is on the stack. "The address to which cPtr points" sounds like they're asking about the memory allocated by malloc; that's on the heap.

– Schwern
Nov 19 '18 at 23:30




1




1





Nothing in the C/C++ standard mandates that anything must end on the stack, or even that the thing known as “stack” exists. You need to look in the assembly output to see what happens, as all of it is implementation-defined. I.e. the question should also state what exact compiler is spoken about, and what compiler options.

– Kuba Ober
Nov 20 '18 at 3:04





Nothing in the C/C++ standard mandates that anything must end on the stack, or even that the thing known as “stack” exists. You need to look in the assembly output to see what happens, as all of it is implementation-defined. I.e. the question should also state what exact compiler is spoken about, and what compiler options.

– Kuba Ober
Nov 20 '18 at 3:04












3 Answers
3






active

oldest

votes


















3














The only true answer is, wherever the compiler feels like. That's probably not the answer you want, so let's examine what a reasonable compiler would probably choose.





  1. cPtr would probably not be stored in memory at all. It fits in a register (pointers almost always fit in CPU registers), and you never take its address, so it will probably be located in one or more registers. It might be written to stack and then read back to preserve its value across the strncpy and printf calls, or its value may be preserved in some other way. (Note that the compiler doesn't need to preserve its value after the free call, since you never use it again.)


  2. malloc will almost always return a heap pointer, since that's where allocating dynamic memory is the easiest, if not the only possible location. So the buffer will be in the heap.

  3. The compiler has a choice here. It might reference a linked malloc from some shared library, in which case it will reside in shared library code, or it might just inline all or part of the function, in which case some or all of it might reside in your program's code.

  4. This assumes a POSIX environment. In every such environment I know, this is handled by a system call, sbrk. Thus, this code will reside within the operating system's kernel code.


EDIT: since some people mentioned the static string, "Good luck on this test", I figured discussing that one would be worthwhile as well. This string appears in three contexts:




  • as a macro replacement (through #define), which is handled by the preprocessor before compiling, and thus doesn't go anywhere at all in the final output;

  • as an argument to the strncpy function, in which case it is included as read-only data, either together with the program's executable code or in a separate section made exclusively for read-only data;

  • as an argument to the sizeof operator. This is the most interesting case of the three. Technically, it should be equivalent to the previous one; however, many compilers can statically calculate the size of a constant string (it's very straightforward, after all), and thus they can replace sizeof(TEXT) with a plain 23 and avoid emitting the string altogether (for that occurrence).






share|improve this answer


























  • +1, but your last bullet about sizeof(TEXT) sounds like you're thinking of strlen, though: sizeof is compile time except for variable length arrays.

    – Rup
    Nov 20 '18 at 7:01













  • @Rup I'm not sure if this is true for all versions of C, though.

    – aaaaaa123456789
    Nov 20 '18 at 7:46



















3














It's actually a bit of a leading question, because it presumes that everything will be in memory.



Local variables, as well as temporary values without a name, are only placed on the stack if necessary. There are different reasons why that might be necessary, for example:




  • The compiler is dumb or made to act dumb by compiling at the lowest possible optimization level.

  • The target machine has an odd architecture without (or very few) registers (rare).

  • There are too many local variables and temporary values live simultaneously to fit them all into registers at that point in the program, so some of them get "spilled". Being spilled is not a property of a variable exactly, but rather of a specific live range. In some sense a variable can therefore move around (if it has multiple associated live ranges and they get allocated differently) and even be in multiple places simultaneously (depending on how you count temporary copies, or unambiguously when loop unrolling is involved).

  • The address of the local variable is taken and used in such a way that the compiler cannot prove that the variable does not need to be in memory (may induce live range splitting so the variable is only actually in memory temporarily).


Most likely none of the above apply (the last item definitely does not apply, the address is not taken) so we should expect cPtr to spend its entire lifetime in registers.



Testing it out on clang targeting x64 we might get code like this:



main:                                   # @main
push rbx
mov edi, 23
call malloc
mov rbx, rax

; at this point, rbx roughly corresponds to cPtr
; it's also still in rax but rax is overwritten by the next operation

movabs rax, 32777976875610985 ; btw this weird number is a piece of string
mov qword ptr [rbx + 15], rax
movups xmm0, xmmword ptr [rip + .L.str]
movups xmmword ptr [rbx], xmm0

; rbx (cPtr) is copied to rdi in order to give it to puts as argument

mov rdi, rbx
call puts
mov rdi, rbx
call free
xor eax, eax
pop rbx
ret
.L.str:
.asciz "Good luck on this test"


Targeting MIPS or ARM or PowerPC with eg GCC shows a similar pattern of cPtr not being on the stack but in a register (or several registers, depending on how you count), though of course the code looks pretty different.



A fun detail of the code above is that while the entire string does appear in a data segment (rodata), a piece of it also appears in the code segment as the immediate operand of that movabs.






share|improve this answer

































    -1















    1. Stack

    2. Heap

    3. Data

    4. Shared library


    That is how i would answer this question.




    1. char * cPtr = NULL; declares a char * on the stack and assigns it to point to NULL, In your instance the malloc() assignes it to point to heap memory but the cPtr variable itself is on the stack.


    2. Malloc allocates heap memory.


    3. The TEXT string is in data segment, and sizeof ("TEXT STRING") will be handled as an operator to an address in data segment. I assume your question means the "code for the arguments to malloc"


    4. Your code doesnt define the function malloc so whatever its doing must be happening due to one of the libraries you #included.



    I may be wrong on one or more of these answers but that is my understanding. If someone can tell me where I am wrong ill correct the answer.






    share|improve this answer
























    • Thanks for the down-vote without any comment! It really helps me fix my answer.

      – Bwebb
      Nov 20 '18 at 1:18






    • 1





      Read other answers to understand what’s wrong. But in general, it’s misguided to talk about what a compiler might do: have you actually looked at what it does, or are you making stuff up? Have you ever checked how well you can predict what a compiler does by writing code, predicting, and checking actual output? You should well get the compiler and look at its output. It’s not magic. Godbolt compiler explorer exists for a reason: so that people don’t have to guess, as such guesses are incorrect more often than not.

      – Kuba Ober
      Nov 20 '18 at 3:07













    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%2f53384055%2fwhere-the-following-objects-are-stored-in-memory%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3














    The only true answer is, wherever the compiler feels like. That's probably not the answer you want, so let's examine what a reasonable compiler would probably choose.





    1. cPtr would probably not be stored in memory at all. It fits in a register (pointers almost always fit in CPU registers), and you never take its address, so it will probably be located in one or more registers. It might be written to stack and then read back to preserve its value across the strncpy and printf calls, or its value may be preserved in some other way. (Note that the compiler doesn't need to preserve its value after the free call, since you never use it again.)


    2. malloc will almost always return a heap pointer, since that's where allocating dynamic memory is the easiest, if not the only possible location. So the buffer will be in the heap.

    3. The compiler has a choice here. It might reference a linked malloc from some shared library, in which case it will reside in shared library code, or it might just inline all or part of the function, in which case some or all of it might reside in your program's code.

    4. This assumes a POSIX environment. In every such environment I know, this is handled by a system call, sbrk. Thus, this code will reside within the operating system's kernel code.


    EDIT: since some people mentioned the static string, "Good luck on this test", I figured discussing that one would be worthwhile as well. This string appears in three contexts:




    • as a macro replacement (through #define), which is handled by the preprocessor before compiling, and thus doesn't go anywhere at all in the final output;

    • as an argument to the strncpy function, in which case it is included as read-only data, either together with the program's executable code or in a separate section made exclusively for read-only data;

    • as an argument to the sizeof operator. This is the most interesting case of the three. Technically, it should be equivalent to the previous one; however, many compilers can statically calculate the size of a constant string (it's very straightforward, after all), and thus they can replace sizeof(TEXT) with a plain 23 and avoid emitting the string altogether (for that occurrence).






    share|improve this answer


























    • +1, but your last bullet about sizeof(TEXT) sounds like you're thinking of strlen, though: sizeof is compile time except for variable length arrays.

      – Rup
      Nov 20 '18 at 7:01













    • @Rup I'm not sure if this is true for all versions of C, though.

      – aaaaaa123456789
      Nov 20 '18 at 7:46
















    3














    The only true answer is, wherever the compiler feels like. That's probably not the answer you want, so let's examine what a reasonable compiler would probably choose.





    1. cPtr would probably not be stored in memory at all. It fits in a register (pointers almost always fit in CPU registers), and you never take its address, so it will probably be located in one or more registers. It might be written to stack and then read back to preserve its value across the strncpy and printf calls, or its value may be preserved in some other way. (Note that the compiler doesn't need to preserve its value after the free call, since you never use it again.)


    2. malloc will almost always return a heap pointer, since that's where allocating dynamic memory is the easiest, if not the only possible location. So the buffer will be in the heap.

    3. The compiler has a choice here. It might reference a linked malloc from some shared library, in which case it will reside in shared library code, or it might just inline all or part of the function, in which case some or all of it might reside in your program's code.

    4. This assumes a POSIX environment. In every such environment I know, this is handled by a system call, sbrk. Thus, this code will reside within the operating system's kernel code.


    EDIT: since some people mentioned the static string, "Good luck on this test", I figured discussing that one would be worthwhile as well. This string appears in three contexts:




    • as a macro replacement (through #define), which is handled by the preprocessor before compiling, and thus doesn't go anywhere at all in the final output;

    • as an argument to the strncpy function, in which case it is included as read-only data, either together with the program's executable code or in a separate section made exclusively for read-only data;

    • as an argument to the sizeof operator. This is the most interesting case of the three. Technically, it should be equivalent to the previous one; however, many compilers can statically calculate the size of a constant string (it's very straightforward, after all), and thus they can replace sizeof(TEXT) with a plain 23 and avoid emitting the string altogether (for that occurrence).






    share|improve this answer


























    • +1, but your last bullet about sizeof(TEXT) sounds like you're thinking of strlen, though: sizeof is compile time except for variable length arrays.

      – Rup
      Nov 20 '18 at 7:01













    • @Rup I'm not sure if this is true for all versions of C, though.

      – aaaaaa123456789
      Nov 20 '18 at 7:46














    3












    3








    3







    The only true answer is, wherever the compiler feels like. That's probably not the answer you want, so let's examine what a reasonable compiler would probably choose.





    1. cPtr would probably not be stored in memory at all. It fits in a register (pointers almost always fit in CPU registers), and you never take its address, so it will probably be located in one or more registers. It might be written to stack and then read back to preserve its value across the strncpy and printf calls, or its value may be preserved in some other way. (Note that the compiler doesn't need to preserve its value after the free call, since you never use it again.)


    2. malloc will almost always return a heap pointer, since that's where allocating dynamic memory is the easiest, if not the only possible location. So the buffer will be in the heap.

    3. The compiler has a choice here. It might reference a linked malloc from some shared library, in which case it will reside in shared library code, or it might just inline all or part of the function, in which case some or all of it might reside in your program's code.

    4. This assumes a POSIX environment. In every such environment I know, this is handled by a system call, sbrk. Thus, this code will reside within the operating system's kernel code.


    EDIT: since some people mentioned the static string, "Good luck on this test", I figured discussing that one would be worthwhile as well. This string appears in three contexts:




    • as a macro replacement (through #define), which is handled by the preprocessor before compiling, and thus doesn't go anywhere at all in the final output;

    • as an argument to the strncpy function, in which case it is included as read-only data, either together with the program's executable code or in a separate section made exclusively for read-only data;

    • as an argument to the sizeof operator. This is the most interesting case of the three. Technically, it should be equivalent to the previous one; however, many compilers can statically calculate the size of a constant string (it's very straightforward, after all), and thus they can replace sizeof(TEXT) with a plain 23 and avoid emitting the string altogether (for that occurrence).






    share|improve this answer















    The only true answer is, wherever the compiler feels like. That's probably not the answer you want, so let's examine what a reasonable compiler would probably choose.





    1. cPtr would probably not be stored in memory at all. It fits in a register (pointers almost always fit in CPU registers), and you never take its address, so it will probably be located in one or more registers. It might be written to stack and then read back to preserve its value across the strncpy and printf calls, or its value may be preserved in some other way. (Note that the compiler doesn't need to preserve its value after the free call, since you never use it again.)


    2. malloc will almost always return a heap pointer, since that's where allocating dynamic memory is the easiest, if not the only possible location. So the buffer will be in the heap.

    3. The compiler has a choice here. It might reference a linked malloc from some shared library, in which case it will reside in shared library code, or it might just inline all or part of the function, in which case some or all of it might reside in your program's code.

    4. This assumes a POSIX environment. In every such environment I know, this is handled by a system call, sbrk. Thus, this code will reside within the operating system's kernel code.


    EDIT: since some people mentioned the static string, "Good luck on this test", I figured discussing that one would be worthwhile as well. This string appears in three contexts:




    • as a macro replacement (through #define), which is handled by the preprocessor before compiling, and thus doesn't go anywhere at all in the final output;

    • as an argument to the strncpy function, in which case it is included as read-only data, either together with the program's executable code or in a separate section made exclusively for read-only data;

    • as an argument to the sizeof operator. This is the most interesting case of the three. Technically, it should be equivalent to the previous one; however, many compilers can statically calculate the size of a constant string (it's very straightforward, after all), and thus they can replace sizeof(TEXT) with a plain 23 and avoid emitting the string altogether (for that occurrence).







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 20 '18 at 0:29

























    answered Nov 20 '18 at 0:20









    aaaaaa123456789aaaaaa123456789

    3,1491227




    3,1491227













    • +1, but your last bullet about sizeof(TEXT) sounds like you're thinking of strlen, though: sizeof is compile time except for variable length arrays.

      – Rup
      Nov 20 '18 at 7:01













    • @Rup I'm not sure if this is true for all versions of C, though.

      – aaaaaa123456789
      Nov 20 '18 at 7:46



















    • +1, but your last bullet about sizeof(TEXT) sounds like you're thinking of strlen, though: sizeof is compile time except for variable length arrays.

      – Rup
      Nov 20 '18 at 7:01













    • @Rup I'm not sure if this is true for all versions of C, though.

      – aaaaaa123456789
      Nov 20 '18 at 7:46

















    +1, but your last bullet about sizeof(TEXT) sounds like you're thinking of strlen, though: sizeof is compile time except for variable length arrays.

    – Rup
    Nov 20 '18 at 7:01







    +1, but your last bullet about sizeof(TEXT) sounds like you're thinking of strlen, though: sizeof is compile time except for variable length arrays.

    – Rup
    Nov 20 '18 at 7:01















    @Rup I'm not sure if this is true for all versions of C, though.

    – aaaaaa123456789
    Nov 20 '18 at 7:46





    @Rup I'm not sure if this is true for all versions of C, though.

    – aaaaaa123456789
    Nov 20 '18 at 7:46













    3














    It's actually a bit of a leading question, because it presumes that everything will be in memory.



    Local variables, as well as temporary values without a name, are only placed on the stack if necessary. There are different reasons why that might be necessary, for example:




    • The compiler is dumb or made to act dumb by compiling at the lowest possible optimization level.

    • The target machine has an odd architecture without (or very few) registers (rare).

    • There are too many local variables and temporary values live simultaneously to fit them all into registers at that point in the program, so some of them get "spilled". Being spilled is not a property of a variable exactly, but rather of a specific live range. In some sense a variable can therefore move around (if it has multiple associated live ranges and they get allocated differently) and even be in multiple places simultaneously (depending on how you count temporary copies, or unambiguously when loop unrolling is involved).

    • The address of the local variable is taken and used in such a way that the compiler cannot prove that the variable does not need to be in memory (may induce live range splitting so the variable is only actually in memory temporarily).


    Most likely none of the above apply (the last item definitely does not apply, the address is not taken) so we should expect cPtr to spend its entire lifetime in registers.



    Testing it out on clang targeting x64 we might get code like this:



    main:                                   # @main
    push rbx
    mov edi, 23
    call malloc
    mov rbx, rax

    ; at this point, rbx roughly corresponds to cPtr
    ; it's also still in rax but rax is overwritten by the next operation

    movabs rax, 32777976875610985 ; btw this weird number is a piece of string
    mov qword ptr [rbx + 15], rax
    movups xmm0, xmmword ptr [rip + .L.str]
    movups xmmword ptr [rbx], xmm0

    ; rbx (cPtr) is copied to rdi in order to give it to puts as argument

    mov rdi, rbx
    call puts
    mov rdi, rbx
    call free
    xor eax, eax
    pop rbx
    ret
    .L.str:
    .asciz "Good luck on this test"


    Targeting MIPS or ARM or PowerPC with eg GCC shows a similar pattern of cPtr not being on the stack but in a register (or several registers, depending on how you count), though of course the code looks pretty different.



    A fun detail of the code above is that while the entire string does appear in a data segment (rodata), a piece of it also appears in the code segment as the immediate operand of that movabs.






    share|improve this answer






























      3














      It's actually a bit of a leading question, because it presumes that everything will be in memory.



      Local variables, as well as temporary values without a name, are only placed on the stack if necessary. There are different reasons why that might be necessary, for example:




      • The compiler is dumb or made to act dumb by compiling at the lowest possible optimization level.

      • The target machine has an odd architecture without (or very few) registers (rare).

      • There are too many local variables and temporary values live simultaneously to fit them all into registers at that point in the program, so some of them get "spilled". Being spilled is not a property of a variable exactly, but rather of a specific live range. In some sense a variable can therefore move around (if it has multiple associated live ranges and they get allocated differently) and even be in multiple places simultaneously (depending on how you count temporary copies, or unambiguously when loop unrolling is involved).

      • The address of the local variable is taken and used in such a way that the compiler cannot prove that the variable does not need to be in memory (may induce live range splitting so the variable is only actually in memory temporarily).


      Most likely none of the above apply (the last item definitely does not apply, the address is not taken) so we should expect cPtr to spend its entire lifetime in registers.



      Testing it out on clang targeting x64 we might get code like this:



      main:                                   # @main
      push rbx
      mov edi, 23
      call malloc
      mov rbx, rax

      ; at this point, rbx roughly corresponds to cPtr
      ; it's also still in rax but rax is overwritten by the next operation

      movabs rax, 32777976875610985 ; btw this weird number is a piece of string
      mov qword ptr [rbx + 15], rax
      movups xmm0, xmmword ptr [rip + .L.str]
      movups xmmword ptr [rbx], xmm0

      ; rbx (cPtr) is copied to rdi in order to give it to puts as argument

      mov rdi, rbx
      call puts
      mov rdi, rbx
      call free
      xor eax, eax
      pop rbx
      ret
      .L.str:
      .asciz "Good luck on this test"


      Targeting MIPS or ARM or PowerPC with eg GCC shows a similar pattern of cPtr not being on the stack but in a register (or several registers, depending on how you count), though of course the code looks pretty different.



      A fun detail of the code above is that while the entire string does appear in a data segment (rodata), a piece of it also appears in the code segment as the immediate operand of that movabs.






      share|improve this answer




























        3












        3








        3







        It's actually a bit of a leading question, because it presumes that everything will be in memory.



        Local variables, as well as temporary values without a name, are only placed on the stack if necessary. There are different reasons why that might be necessary, for example:




        • The compiler is dumb or made to act dumb by compiling at the lowest possible optimization level.

        • The target machine has an odd architecture without (or very few) registers (rare).

        • There are too many local variables and temporary values live simultaneously to fit them all into registers at that point in the program, so some of them get "spilled". Being spilled is not a property of a variable exactly, but rather of a specific live range. In some sense a variable can therefore move around (if it has multiple associated live ranges and they get allocated differently) and even be in multiple places simultaneously (depending on how you count temporary copies, or unambiguously when loop unrolling is involved).

        • The address of the local variable is taken and used in such a way that the compiler cannot prove that the variable does not need to be in memory (may induce live range splitting so the variable is only actually in memory temporarily).


        Most likely none of the above apply (the last item definitely does not apply, the address is not taken) so we should expect cPtr to spend its entire lifetime in registers.



        Testing it out on clang targeting x64 we might get code like this:



        main:                                   # @main
        push rbx
        mov edi, 23
        call malloc
        mov rbx, rax

        ; at this point, rbx roughly corresponds to cPtr
        ; it's also still in rax but rax is overwritten by the next operation

        movabs rax, 32777976875610985 ; btw this weird number is a piece of string
        mov qword ptr [rbx + 15], rax
        movups xmm0, xmmword ptr [rip + .L.str]
        movups xmmword ptr [rbx], xmm0

        ; rbx (cPtr) is copied to rdi in order to give it to puts as argument

        mov rdi, rbx
        call puts
        mov rdi, rbx
        call free
        xor eax, eax
        pop rbx
        ret
        .L.str:
        .asciz "Good luck on this test"


        Targeting MIPS or ARM or PowerPC with eg GCC shows a similar pattern of cPtr not being on the stack but in a register (or several registers, depending on how you count), though of course the code looks pretty different.



        A fun detail of the code above is that while the entire string does appear in a data segment (rodata), a piece of it also appears in the code segment as the immediate operand of that movabs.






        share|improve this answer















        It's actually a bit of a leading question, because it presumes that everything will be in memory.



        Local variables, as well as temporary values without a name, are only placed on the stack if necessary. There are different reasons why that might be necessary, for example:




        • The compiler is dumb or made to act dumb by compiling at the lowest possible optimization level.

        • The target machine has an odd architecture without (or very few) registers (rare).

        • There are too many local variables and temporary values live simultaneously to fit them all into registers at that point in the program, so some of them get "spilled". Being spilled is not a property of a variable exactly, but rather of a specific live range. In some sense a variable can therefore move around (if it has multiple associated live ranges and they get allocated differently) and even be in multiple places simultaneously (depending on how you count temporary copies, or unambiguously when loop unrolling is involved).

        • The address of the local variable is taken and used in such a way that the compiler cannot prove that the variable does not need to be in memory (may induce live range splitting so the variable is only actually in memory temporarily).


        Most likely none of the above apply (the last item definitely does not apply, the address is not taken) so we should expect cPtr to spend its entire lifetime in registers.



        Testing it out on clang targeting x64 we might get code like this:



        main:                                   # @main
        push rbx
        mov edi, 23
        call malloc
        mov rbx, rax

        ; at this point, rbx roughly corresponds to cPtr
        ; it's also still in rax but rax is overwritten by the next operation

        movabs rax, 32777976875610985 ; btw this weird number is a piece of string
        mov qword ptr [rbx + 15], rax
        movups xmm0, xmmword ptr [rip + .L.str]
        movups xmmword ptr [rbx], xmm0

        ; rbx (cPtr) is copied to rdi in order to give it to puts as argument

        mov rdi, rbx
        call puts
        mov rdi, rbx
        call free
        xor eax, eax
        pop rbx
        ret
        .L.str:
        .asciz "Good luck on this test"


        Targeting MIPS or ARM or PowerPC with eg GCC shows a similar pattern of cPtr not being on the stack but in a register (or several registers, depending on how you count), though of course the code looks pretty different.



        A fun detail of the code above is that while the entire string does appear in a data segment (rodata), a piece of it also appears in the code segment as the immediate operand of that movabs.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 20 '18 at 0:29

























        answered Nov 20 '18 at 0:24









        haroldharold

        41.3k357108




        41.3k357108























            -1















            1. Stack

            2. Heap

            3. Data

            4. Shared library


            That is how i would answer this question.




            1. char * cPtr = NULL; declares a char * on the stack and assigns it to point to NULL, In your instance the malloc() assignes it to point to heap memory but the cPtr variable itself is on the stack.


            2. Malloc allocates heap memory.


            3. The TEXT string is in data segment, and sizeof ("TEXT STRING") will be handled as an operator to an address in data segment. I assume your question means the "code for the arguments to malloc"


            4. Your code doesnt define the function malloc so whatever its doing must be happening due to one of the libraries you #included.



            I may be wrong on one or more of these answers but that is my understanding. If someone can tell me where I am wrong ill correct the answer.






            share|improve this answer
























            • Thanks for the down-vote without any comment! It really helps me fix my answer.

              – Bwebb
              Nov 20 '18 at 1:18






            • 1





              Read other answers to understand what’s wrong. But in general, it’s misguided to talk about what a compiler might do: have you actually looked at what it does, or are you making stuff up? Have you ever checked how well you can predict what a compiler does by writing code, predicting, and checking actual output? You should well get the compiler and look at its output. It’s not magic. Godbolt compiler explorer exists for a reason: so that people don’t have to guess, as such guesses are incorrect more often than not.

              – Kuba Ober
              Nov 20 '18 at 3:07


















            -1















            1. Stack

            2. Heap

            3. Data

            4. Shared library


            That is how i would answer this question.




            1. char * cPtr = NULL; declares a char * on the stack and assigns it to point to NULL, In your instance the malloc() assignes it to point to heap memory but the cPtr variable itself is on the stack.


            2. Malloc allocates heap memory.


            3. The TEXT string is in data segment, and sizeof ("TEXT STRING") will be handled as an operator to an address in data segment. I assume your question means the "code for the arguments to malloc"


            4. Your code doesnt define the function malloc so whatever its doing must be happening due to one of the libraries you #included.



            I may be wrong on one or more of these answers but that is my understanding. If someone can tell me where I am wrong ill correct the answer.






            share|improve this answer
























            • Thanks for the down-vote without any comment! It really helps me fix my answer.

              – Bwebb
              Nov 20 '18 at 1:18






            • 1





              Read other answers to understand what’s wrong. But in general, it’s misguided to talk about what a compiler might do: have you actually looked at what it does, or are you making stuff up? Have you ever checked how well you can predict what a compiler does by writing code, predicting, and checking actual output? You should well get the compiler and look at its output. It’s not magic. Godbolt compiler explorer exists for a reason: so that people don’t have to guess, as such guesses are incorrect more often than not.

              – Kuba Ober
              Nov 20 '18 at 3:07
















            -1












            -1








            -1








            1. Stack

            2. Heap

            3. Data

            4. Shared library


            That is how i would answer this question.




            1. char * cPtr = NULL; declares a char * on the stack and assigns it to point to NULL, In your instance the malloc() assignes it to point to heap memory but the cPtr variable itself is on the stack.


            2. Malloc allocates heap memory.


            3. The TEXT string is in data segment, and sizeof ("TEXT STRING") will be handled as an operator to an address in data segment. I assume your question means the "code for the arguments to malloc"


            4. Your code doesnt define the function malloc so whatever its doing must be happening due to one of the libraries you #included.



            I may be wrong on one or more of these answers but that is my understanding. If someone can tell me where I am wrong ill correct the answer.






            share|improve this answer














            1. Stack

            2. Heap

            3. Data

            4. Shared library


            That is how i would answer this question.




            1. char * cPtr = NULL; declares a char * on the stack and assigns it to point to NULL, In your instance the malloc() assignes it to point to heap memory but the cPtr variable itself is on the stack.


            2. Malloc allocates heap memory.


            3. The TEXT string is in data segment, and sizeof ("TEXT STRING") will be handled as an operator to an address in data segment. I assume your question means the "code for the arguments to malloc"


            4. Your code doesnt define the function malloc so whatever its doing must be happening due to one of the libraries you #included.



            I may be wrong on one or more of these answers but that is my understanding. If someone can tell me where I am wrong ill correct the answer.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 19 '18 at 23:42









            BwebbBwebb

            3358




            3358













            • Thanks for the down-vote without any comment! It really helps me fix my answer.

              – Bwebb
              Nov 20 '18 at 1:18






            • 1





              Read other answers to understand what’s wrong. But in general, it’s misguided to talk about what a compiler might do: have you actually looked at what it does, or are you making stuff up? Have you ever checked how well you can predict what a compiler does by writing code, predicting, and checking actual output? You should well get the compiler and look at its output. It’s not magic. Godbolt compiler explorer exists for a reason: so that people don’t have to guess, as such guesses are incorrect more often than not.

              – Kuba Ober
              Nov 20 '18 at 3:07





















            • Thanks for the down-vote without any comment! It really helps me fix my answer.

              – Bwebb
              Nov 20 '18 at 1:18






            • 1





              Read other answers to understand what’s wrong. But in general, it’s misguided to talk about what a compiler might do: have you actually looked at what it does, or are you making stuff up? Have you ever checked how well you can predict what a compiler does by writing code, predicting, and checking actual output? You should well get the compiler and look at its output. It’s not magic. Godbolt compiler explorer exists for a reason: so that people don’t have to guess, as such guesses are incorrect more often than not.

              – Kuba Ober
              Nov 20 '18 at 3:07



















            Thanks for the down-vote without any comment! It really helps me fix my answer.

            – Bwebb
            Nov 20 '18 at 1:18





            Thanks for the down-vote without any comment! It really helps me fix my answer.

            – Bwebb
            Nov 20 '18 at 1:18




            1




            1





            Read other answers to understand what’s wrong. But in general, it’s misguided to talk about what a compiler might do: have you actually looked at what it does, or are you making stuff up? Have you ever checked how well you can predict what a compiler does by writing code, predicting, and checking actual output? You should well get the compiler and look at its output. It’s not magic. Godbolt compiler explorer exists for a reason: so that people don’t have to guess, as such guesses are incorrect more often than not.

            – Kuba Ober
            Nov 20 '18 at 3:07







            Read other answers to understand what’s wrong. But in general, it’s misguided to talk about what a compiler might do: have you actually looked at what it does, or are you making stuff up? Have you ever checked how well you can predict what a compiler does by writing code, predicting, and checking actual output? You should well get the compiler and look at its output. It’s not magic. Godbolt compiler explorer exists for a reason: so that people don’t have to guess, as such guesses are incorrect more often than not.

            – Kuba Ober
            Nov 20 '18 at 3:07




















            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%2f53384055%2fwhere-the-following-objects-are-stored-in-memory%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

            Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

            Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

            A Topological Invariant for $pi_3(U(n))$