1

This is an example from a book I am reading, to demonstrate the use of heap memory.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
    char *char_ptr;
    int *int_ptr;
    int mem_size;

    if (argc < 2) //if not given an argument, defaukt memory size is 50//
       mem_size = 50;
    else
        mem_size = atoi(argv[1]);

    printf("\t[+] allocating %d bytes of memory on the heap for char_ptr\n", mem_size); //memory is given, and passed to char pointer//
    char_ptr = (char *)malloc(mem_size);

    if(char_ptr == NULL) { //check for error//
        fprintf(stderr, "Error: could not allocate memory.\n");
        exit(-1);
   }

    strcpy(char_ptr, "This memory is located on the heap.");
    printf("char_ptr (%p) --> '%s'\n", char_ptr, char_ptr);

    printf("\t[+] allocating 12 bytes of memory on the heap for int_ptr\n");
    int_ptr = (int *)malloc(12);

    if(int_ptr == NULL) {
        fprintf(stderr, "Error: coud not allocate heap memory.\n");
        exit(-1);
    }

    *int_ptr = 31337;
    printf("int_ptr (%p) --> %d\n", int_ptr, *int_ptr);

    printf("\t[-] freeing char_ptr's heap memory...\n");
    free(char_ptr);

    printf("\t[+] allocating another 15 bytes for char_ptr\n");
    char_ptr = (char *)malloc(15);

    if(char_ptr == NULL) {
        fprintf(stderr, "Error: coud not allocate heap memory.\n");
        exit(-1);
    }

    strcpy(char_ptr, "new memory");
    printf("char_ptr (%p) --> '%s'\n", char_ptr, char_ptr);

    printf("\t[-] freeing int_ptr's heap memor...\n");
    free(int_ptr);
}

I am confused about this line: strcpy(char_ptr, "This memory is located on the heap.");

char_ptr already contains the address of allocated heap memory, so how does this text get copied into the pointer? It seems the address of allocated heap memory also did not change, from looking at printf("char_ptr (%p) --> '%s'\n", char_ptr, char_ptr);. Does this basically mean the pointer contains two values? How does this work?

kingvon@KingVon:~/Desktop/asm$ ./a.out
        [+] allocating 50 bytes of memory on the heap for char_ptr char_ptr (0x55ef60d796b0) --> 'This memory is located on the heap.'
        [+] allocating 12 bytes of memory on the heap for int_ptr int_ptr (0x55ef60d796f0) --> 31337
        [-] freeing char_ptr's heap memory...
        [+] allocating another 15 bytes for char_ptr char_ptr (0x55ef60d79710) --> 'new memory'
        [-] freeing int_ptr's heap memor...
        [-] freeing char_ptr's heap memory...
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
raincouver
  • 61
  • 7

2 Answers2

1

Does this basically mean the pointer contains two values?

No – the char_ptr variable can only have one particular value – that will be (following a successful call to malloc) the starting address of a block of the specified number of bytes in memory. Just that – an address.

What may be confusing you is how that address is used/interpreted in your subsequent code.

The strcpy(char_ptr, "This memory is located on the heap."); line uses that address when it copies the data from the second argument (the string literal) into the bytes starting at that address – and it continues doing so until it finds the nul-terminator at the end of that literal (which it will also copy, and then stop).

The printf("char_ptr (%p) --> '%s'\n", char_ptr, char_ptr); call is a bit more subtle. Although you are giving the same address (exactly) as both arguments, the way that address is interpreted by the printf function is determined by the corresponding format arguments. For the first instance, the %p specifier tells the function to print the actual value of the address; for the second instance, the %s specifier tells it to print out the characters, in order, starting at the given address, and stopping when it finds the first nul (zero) character.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • What if it was `strcpy(*char_ptr, "This memory is located on the heap.");`? Wouldn't this mean the same thing since dereferencing a pointer means the actual value of the memory address it is pointing to? – raincouver Jan 16 '21 at 23:27
  • @raincouver No - that would fail catastrophically! You would be trying to use the *value* of the `char` stored at the memory location as an address, and that would be very wrong. Imagine a long line of boxes, each of which contain a piece of paper with a number on it. The number *of* the box (its address) is not the same as the number *in* the box (its value). – Adrian Mole Jan 16 '21 at 23:29
  • ok, makes a lot of sense, so in this context since strcpy expects a memory address(or the number of the box) as its argument, it would be appropriate to just include the pointer. Also when printf is given %p to print char_ptr, is it printing the address of the pointer itself or the address it is pointing to ? – raincouver Jan 16 '21 at 23:34
  • The `%p` specifier prints the address that the pointer contains. It can be confusing, but the pointer is *itself* a box that contains the address of another box. – Adrian Mole Jan 16 '21 at 23:55
1

strcpy copies a null terminated C string into the memory pointed to by the first argument.

No it does not contain two values. A pointer has its own value which is a memory address, and it POINTS TO the values at that memory address. That can be one thing, or an array of things. In the case of a character pointer it is the first character in an array. An array of characters with a NUL, aka 0 character at the end is a C string.

Zan Lynx
  • 53,022
  • 10
  • 79
  • 131