Pointer Concepts

I am problem set 6 and very confused by the use of pointers. Please tell me the difference of these things first?

1. What is the difference between char word[length] and char *word = malloc(sizeof(char) * LENGTH)??
2. In char * word, what is the meaning of &word, word and *word?
3. What is the meaning of NULL in pointer, does it mean word points to memory but memory have nothing OR word doesn't point to memory at all in case word has NULL?
4. If there is function that receive something as pointer, How do i pass an argument to it? For example i want to send char * word as parameter, How do i do it?

Thank you very much for your consideration.

First, recall that pointers are variables which contain an address to some other variable. So if you have a variable int* n, this defines a variable n, which contains the address of some place in memory of where to find an integer.

Each location in memory is given a unique number. Pointers are numbers which refer to locations in memory. So a pointer with the value 1000 will refer to whatever happens to be at the 1000th location in memory.

What is the difference between char word[length] and char *word = malloc(sizeof(char) * LENGTH)??

A program written in C uses two places to store things, namely the stack and the heap.

The stack is used to store local variables. Any variable you type out in code will be stored on the stack. When a function is called, all the variables in the function are added to the stack while the function is running. When the function returns, all the variables are removed from the stack. This is referred to as static memory since the size cannot change while the program is running.

The heap is used to store things which can change while your program is running. This is called dynamic memory since it can change. While the program is running it will calculate how much memory it needs, and "allocate" that space on the heap. The operating system (OS) will find an unused chunk of memory of the requested size, which no-one else is using, and return a pointer to it, so that the program knows where to access the memory. This is what char *word = malloc(sizeof(char) * LENGTH) is doing - it's asking the operating system to find it a piece of memory which is LENGTH number of chars large.

One analogy might be to think of the stack like your house, and the heap as everything outside it. You lay out the plans for your house by writing code. When the program runs, it's like the house is built from the plans. Once the house is built it is a certain size and shape and (generally) does not change.

Now say you want to keep some elephants (a large amount of data). You could keep the elephants in some rooms in your house (keep data on the stack), but then you could run out of space if you design your house too small, or you could end up wasting space if you design your house too large.

You could also just keep them outside (allocate data on the heap). So you ask the city (the operating system) for a zone to keep your elephants. The city allocates some land, and gives you a note with the address of where your elephant is kept. This is the pointer to the elephant. When you want to look at the elephant, you read the address off the note, and go to that location.

You still keep the pointer (the letter) in the stack (the house), but it takes up much less space in your program compared to storing the data (the elephant). The other advantage is if you need space for more data (more elephants), you only need to ask the city (the operating system) for more space.

In char * word, what is the meaning of &word, word and *word?

1. word is a the location of a char variable somewhere in memory. There may be many chars stored after this location, but the pointer refers to the first char. This will be some number which is a memory location, e.g. 0xBAADF00D.
2. *word is the value that word points to. In the case of a char, this will refer to some ASCII character, e.g. A.
3. &word in this context makes little sense. It's basically getting the location of word, or in other words, converting into a pointer. In your example word is already a pointer, so you're asking for the address of a pointer.

Some vocabulary might help when reading and writing code dealing with pointers.

1. First rule, read pointer definitions from right to left. For example:

char * word

Read this as word is a * (pointer to) a char.

2. When you write n = *word, or *word = 'A', you are dereferencing the pointer, or in other words, "going to the location that the pointer refers to". Another way to think of this, is you are converting a pointer back into the type that it refers to. So in your scenario *word, means "get the value that word points to".

3. & is the "address of" operator. This is saying, get the location in memory of where a variable is stored. For example, if you have a variable char word, using &word will give you a pointer to word.

What is the meaning of NULL in pointer, does it mean word points to memory but memory have nothing OR word doesn't point to memory at all in case word has NULL?

NULL is directly equivalent to 0. Using your earlier example, if you have a variable char* word = NULL, this is like saying char* word = 0. In theory it's referring to the very first byte (the zeroth byte) in memory, although in practice the program takes this to mean that it refers to nothing.

In other words, word will have an address which is exactly 0. Using the prior example of the letter, this is like saying you have a letter but the address on it is blank.

If there is function that receive something as pointer, How do i pass an argument to it? For example i want to send char * word as parameter, How do i do it?

Such a function definition might look like this:

void swap(int* a, int* b)
{
// swap *a with *b
}

This function requires a pointer to an int. There are two ways to pass the variable to the function, depending on the type of the source variable. If the variable being passed in is a pointer, then it can be used as-is, because it is already the same type:

int* a = NULL;
int* b = NULL;
// allocate memory for a and b, and assign values
swap(a, b);

However, if the variable is not a pointer, but instead a local stack variable, then it first needs to be converted to a pointer, using the "address-of" operator &:

int a = 7;
int b = 3;
swap(&a, &b);
• Thank you very much Luke. My mind was really upside down. Nicely tackled
– HKH
Aug 15 '14 at 15:24
• Clearly elaborated! Oct 30 '14 at 12:11

What is the difference between char word[length] and char *word = malloc(sizeof(char) * LENGTH)??

A char * is a pointer to a char (or a sequence of chars -- aka a string) while a char[] is an array of chars. They're both interchangeably used, but here are some main differences.

1. If you use a char *, as a member of a struct, you have to allocate memory for it separately using malloc() while if you used a char[], all you need to do is to specify the size of that array. So for example, given these 2 structs,

typedef struct s1
{
char *str;
}
s1;

// some code
s1 *ptr1 = malloc(sizeof(s1)); // allocate memory for an s1

// if we wanna use ptr1->str, we have to allocate memory separately for it
ptr1->str = malloc(sizeof(LENGTH)); // allocate memory for str

// some code

On the other hand,

typedef struct s2
{
char arr[LENGTH];
}
s2;

// some code
s2 *ptr2 = malloc(sizeof(s2)); // allocate memory for an s2

// you can now initialize ptr2->arr directly here without mallocing memory for it

2. Since you're allocating memory for char * variables separately, you also need to free them separately while a char[] is automatically freed when you call free() on a pointer to this specific struct. For example,

// free data
free(ptr1->str); // we have to free ptr->str first
free(ptr1); // then free ptr itself

On the other hand,

// free data
free(ptr2); // no need to free ptr2->arr

3. One last thing is that you won't be able to initialize a char[] with a string literal if you've declared it separately as it's the case here. You have to initialize it character by character while a char * can be initialized with a string literal anytime even if you didn't allocate memory for it and of course you won't need to free it separately in this case since you didn't malloc memory for it at the first place. So for example,

ptr1->str = "hello"; // initialize ptr->str

On the other hand,

// initialize ptr2->arr
ptr2->arr = 'h';
ptr2->arr = 'e';
ptr2->arr = 'l';
ptr2->arr = 'l';
ptr2->arr = 'o';
ptr2->arr = '\0';

It's worth mentioning that initializing a char * with a string literal won't let you edit any of the its characters afterwards.

In char * word, what is the meaning of &word,word and *word?

In this situation, word is a pointer to a char (or a sequence of chars). It contains the address of the block of memory it points to. &word is the address of that pointer. It returns the address of word. *word dereferences the address that word contains which gives us the first character in that block (since the address of the first character is the same as the address of the whole block). This answer has a good visual representation to this.

What is the meaning of NULL in pointer, does it mean word points to memory but memory have nothing OR word doesn't point to memory at all in case word has NULL?

NULL is a special value. It represents a memory address. It's actually equal to 0x0 and that's the zeroth location in memory. And it's a special location that you can't read/write data from and to it. Usually we set pointer values to NULL when we want them to point to nothing.

If there is function that receive something as pointer, How do i pass an argument to it? For example i want to send char * word as parameter, How do i do it?

Given this simple program,

#include <stdio.h>

// prototypes
unsigned int getLength(char *str);

int main(void)
{
char *str = "hello"; // create a string
unsigned int l = getLength(str); // pass str to a function
printf("Length: %u\n", l); // print the length
}

unsigned int getLength(char *str) // accepts a char *
{
// calculate the length of str
unsigned int length = 0;

// while the current character is not the null terminator
while (str[length] != '\0')
{
length++; // increase the length by 1
}

return length;
}

Hope that helps!

• Thank you very much kareem. Suddenly there were too many pointers involved in problem set 6 and it really helped.
– HKH
Aug 15 '14 at 15:22