I need to make an array of structs dynamically and I don't know the size when executing the malloc command. So I thought I could use realloc every time I need another struct! For example this code:
main:
int main(void) {
flights *flight_list = NULL;
int numFlights = 0;
numFlights = load_flights(&flight_list);
/* output flights. Problem: Only first flight is there, the second is not allocated! */
Here's the function:
short load_flights(flights **flight_list) {
flight_list[0] = calloc(1, sizeof(flights));
flight_list[0]->price = 69;
flight_list[0] = realloc(*flight_list, sizeof(flights)*2);
flight_list[1]->price = 70;
return 2; //num of flights-structs
The problem is, that actually 2 elements should be created, but only 1 element is there - check this debugging screenshot:
As you can see, flight_list[0] is there, but flight_list[1] not! But realloc should do the job?
Am I understanding anything wrong?
There's a bug in this line:
flight_list[1]->price = 70;
Both [] and -> dereference pointers. a[b] is equivalent to *(a+b) and a->b is equivalent to (*a).b. Your line therefore means:
(**(flight_list + 1)).price = 70;
However, flight_list (in load_flights) is a pointer to the flight_list variable in main! In the context of main, you're computing &flight_list + 1, which is an invalid pointer: You're getting the contents of memory that happens to be next to a local variable.
The correct code would be:
(*(*flight_list + 1)).price = 70;
*flight_list is the pointer returned by realloc. Here we can step one element ahead in the dynamic array.
We can also write this as:
(*flight_list)[1].price = 70;
Your flight_list is an array of pointers to pointers of flights.
With flight_list[0] = realloc(*flight_list, sizeof(flights)*2); you allocate space for two flights to the item flight_list[0], but flight_list itself remains unchanged. In fact, there is no code that allocates any space for flight_list at all, but maybe you just left out this code in your example.
If the realloc line of code is what you wanted, you should watch these memory locations in the debugger: flight_list[0][0] for the first flight, and flight_list[0][1] for the second.
I'm currently trying to do something simple, turn my list of nodes into an array of pointers to the nodes, so that I could use it for another functionality.
typedef struct {
int data;
} myNode;
In the function where I'm trying to make my array of node pointers, I write something like (assume I have a list called myList of all the nodes):
myNode** aryPtr = malloc(sizeof(myNode*)) * numItemsInList);
and for each spot, I allocate memory for the pointer doing:
int inc = 0;
int z = 0;
aryPtr[inc] = malloc(sizeof(myNode));
aryPtr[inc] = &(myList[z]);
inc += 1;
z += 1;
I've been trying to do something like this to go about storing the pointers to each of my nodes in an array, but haven't had success and don't entirely understand how to make an array of pointers (using a double pointer). Any help on how to store pointers into a dynamically allocated array of pointers would help a lot.
These two lines are a little problematic:
aryPtr[inc] = malloc(sizeof(myNode));
aryPtr[inc] = &(myList[z]);
The first assignment
aryPtr[inc] = malloc(sizeof(myNode));
allocates memory, and makes aryPtr[inc] point to that memory. But the next assignment
aryPtr[inc] = &(myList[z]);
throws away the result of the malloc call, and reassigns aryPtr[inc] to point somewhere else. That leads to a memory leak.
It's similar to having a simple int variable, and assigning it multiple times:
int a;
a = 5;
a = 10;
And then wonder why a is not equal to 5.
To solve this problem, either drop the first assignment with the malloc and only have
aryPtr[inc] = &myList[z]; // Make aryPtr[inc] point to myList[z]
Or dereference the destination pointer to copy the structure:
aryPtr[inc] = malloc(sizeof(myNode));
*aryPtr[inc] = myList[z]; // Copy the structure itself
Another couple of things:
With the code you show (you really need to provide a proper Minimal, Complete, and Verifiable Example) it looks like you're always using index 0 for both aryPtr and myList. You also use the same index for both aryPtr and myList, so you only need a single variable for that.
To build nested TLV elements (e.g., 6F1A840E315041592E5359532E4444463031A5088801025F2D02656E), I'm using the following data structure:
typedef struct Element
{
int16_t nTag; // Tells you if pValue points to a primitive value or constructed one
uint16_t nLength;
void *pValue; // Could be either unsigned char* or TlvElement*
} TlvElement;
How can I implement a function that properly deallocates the memory used by the nested TLV elements?
// Let's build TLV data: 6F04A5020000
TlvElement *pTlvElement = (TlvElement*)malloc(sizeof(TlvElement));
pTlvElement->nTag = 0x6F;
pTlvElement->nLength = 4;
pTlvElement->pValue = malloc(sizeof(TlvElement)); // pValue points to another TLV element
TlvElement *pTlvElementChild = (TlvElement*)pTlvElement->pValue;
pTlvElementChild->nTag = 0xA5;
pTlvElementChild->nLength = 2;
pTlvElementChild->pValue = malloc(2 * sizeof(unsigned char)); // pValue points to a byte array
memset(pTlvElementChild->pValue, 0, 2);
Deallocate(pTlvElement);
//free(pTlvElementChild->pValue);
//free(pTlvElement->pValue);
//free(pTlvElement);
You just deallocate it in the order you gave in the commented lines:
free((TlvElement *)(pTlvElement->pValue)->pValue);
free(pTlvElement->pValue);
free(pTlvElement);
The function free(void *) takes a void *, so the compiler wont complain. The only cast you need is to access the field pValue of the child element.
A word of caution: unless the tag already marks this, you might consider to add keep somewhere that the element does indeed contain a child element.
Assuming the value of ->nTag field can be used for this, you can deallocate the child elements recursively:
void Deallocate(TlvElement *e)
{
if (e->nTag == 0x6f)
Deallocate((TlvElement *)e->pValue);
else
free(e->pValue)
free(e);
}
You might want to take precautions against endless recursion, though.
Having considerable trouble with some pointer arithmatic. I think I get the concepts (pointer variables point to a memory address, normal variables point to data) but I believe my problem is with the syntax (*, &, (*), *(), etc.)
What I want to do is build dynamic arrays of a custom struct (i.e. arrays of pointers to heap structs), and my interface provides two methods, "ad_to_obj_array" (which takes the object to add and the array which can be null for empty) and "obj_array_dustbin" (which just takes the array to dispose, also disposing of the contents, the heap objs). The former is rendered below.
The details of the objects are not important (and the struct has been renamed anyway) but my solution to the general problem is below, and I'd be grateful if you can spot the error. The compiler is complaining about an invalid lvalue, where I try and assign the address in the pointer on the RHS to the pointer value in an array of pointers to heap structs:
#define NUM_ELEM(x) (sizeof (x) / sizeof (*(x)))
obj* add_to_obj_array(obj* new_obj, obj* array)
{
int number_of_elements = 0;
if (array != NULL)
{
number_of_elements = NUM_ELEM(array);
}
obj* new_array = NULL;
/* note: I am expecting sizeof(new_obj) to return the size of an obj*
to go into the array of pointers. */
if ( NULL ==
(new_array = (obj*)malloc((number_of_elements + 1)* sizeof(new_obj))) )
{
/* memory request refused :( */
return NULL;
}
/* copy the old array pointers into the new array's pointer slots: */
int i;
for (i = 0; i < number_of_elements; i++)
{
&(new_array[i]) = &(array[i]);
}
/* add the new item to the end (assign pointer value directly): */
new_array[number_of_elements] = new_obj;
if (number_of_elements > 0)
{
free(&array);
}
return new_array;
}
Now, I have tried the following permutations of the offending line:
&(new_array[i]) = &(array[i]);
*(new_array[i]) = &(array[i]);
new_array[i] = &(array[i]);
and all give a compiler error of one sort or another. I am fairly sure that the right hand side is the address of the ith element of the old array, but how to I assign to the ith element of the new, when the elements of the array are pointers to structs?
EDIT - please note, the macro NUM_ELEM above DOES NOT WORK; it will always return 1. See #Merlyn Morgan-Graham's answer below for why.
Based on your description, you're starting off wrong, so by the time you get to copying things, nothing you can do is likely to work.
Right now, you've defined new_array (and, presumably, array) as a pointer to obj. The result looks like this:
In this case, you have a pointer to a dynamically allocated array of objects. When/if you expand the allocation, you'll need to copy all the objects themselves.
According to your description: "(i.e. arrays of pointers to heap structs)", what you want is an array of pointers. If you want to allocate that array of pointers automatically, your definition would look like:
obj *array[NUMBER];
My guess is that's not what you want though. Presumably, you want to allocate that array dynamically as well. That would look like this:
In this case, new_array and array will each need to be defined as a pointer to pointer to obj. You'd then allocate an array of pointers (i.e., pointers to as many objs as you want) and have each point point at an obj:
obj **new_array;
// allocate an array of pointers with space to point at more items:
new_array = malloc(sizeof(obj *) * new_elements);
// copy the pointers to the current items to the new array:
for (i=0; i<current_elements; i++)
new_array[i] = array[i];
The advantage of this is that when you do the copying, you only copy pointers, not the objects themselves. Especially with large objects, this can save a substantial amount of effort. The tradeoff is that using an element goes through two levels of indirection intead of one, so the reference may be slower (though rarely much slower, especially on a relatively high-performance processor).
As #rerun already pointed out, in either case you probably want to use realloc. In particular, this might be able to expand an allocation "in place", and avoid copying data as often. Of course, that's not guaranteed, but at least you're giving it a chance; if you malloc and copy every time, you eliminate even the possibility of that optimization.
You have two arrays doesn't new_array[i] = array[i] do what you need.
Have you looked at realloc as a possible solution.
Just assign the values across. new_array[i] = array[i].
The problem you may be running into is that, for obj* to actually be an array of pointers, obj must itself be a pointer type:
typedef struct
{
int value1;
} obj_pool;
typedef obj_pool* obj;
int main(int argc, char* argv[])
{
obj_pool pool1;
pool1.value1 = 5;
obj array[] = { &pool1 };
array[0]->value1 = 16;
return 0;
}
Another problem you'll run into once you get this compiling is that sizeof(array) == sizeof(obj*). NUM_ELEM(array) will always return the same value. This means you'll have to pass a size_t array_size parameter to your function.
in your code elements of the array are not pointers on the structure, they are structure objects. elements of the this array obj** array are pointers on the structure obj.
#define NUM_ELEM(x) (sizeof (x) / sizeof (*(x)))
void add_to_obj_array(obj* new_obj, obj** array)
{
int number_of_elements = 0;
if (array != NULL)
{
number_of_elements = NUM_ELEM(array);
}
// expand array with one more item
array = (obj**)realloc(array, (number_of_elements + 1) * sizeof(new_obj));
if (array == NULL )
{
/* memory request refused :( */
return;
}
// Put new item at the last place on the array
array[number_of_elements] = new_obj;
}
So here we used matrix (pointer on pointers of the obj structure). When we add new element we simply expand existing array for one place and on that place we put new structure object. There is no need to return value because we operate on the pointers of the objects, and all change is done on actual objects, not on their copies.
How do pointers-to-pointers work in C?
When might you use them?
Let's assume an 8 bit computer with 8 bit addresses (and thus only 256 bytes of memory). This is part of that memory (the numbers at the top are the addresses):
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
| | 58 | | | 63 | | 55 | | | h | e | l | l | o | \0 | |
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
What you can see here, is that at address 63 the string "hello" starts. So in this case, if this is the only occurrence of "hello" in memory then,
const char *c = "hello";
... defines c to be a pointer to the (read-only) string "hello", and thus contains the value 63. c must itself be stored somewhere: in the example above at location 58. Of course we can not only point to characters, but also to other pointers. E.g.:
const char **cp = &c;
Now cp points to c, that is, it contains the address of c (which is 58). We can go even further. Consider:
const char ***cpp = &cp;
Now cpp stores the address of cp. So it has value 55 (based on the example above), and you guessed it: it is itself stored at address 60.
As to why one uses pointers to pointers:
The name of an array usually yields the address of its first element. So if the array contains elements of type t, a reference to the array has type t *. Now consider an array of arrays of type t: naturally a reference to this 2D array will have type (t *)* = t **, and is hence a pointer to a pointer.
Even though an array of strings sounds one-dimensional, it is in fact two-dimensional, since strings are character arrays. Hence: char **.
A function f will need to accept an argument of type t ** if it is to alter a variable of type t *.
Many other reasons that are too numerous to list here.
How do pointers to pointers work in C?
First a pointer is a variable, like any other variable, but that holds the address of a variable.
A pointer to a pointer is a variable, like any other variable, but that holds the address of a variable. That variable just happens to be a pointer.
When would you use them?
You can use them when you need to return a pointer to some memory on the heap, but not using the return value.
Example:
int getValueOf5(int *p)
{
*p = 5;
return 1;//success
}
int get1024HeapMemory(int **p)
{
*p = malloc(1024);
if(*p == 0)
return -1;//error
else
return 0;//success
}
And you call it like this:
int x;
getValueOf5(&x);//I want to fill the int varaible, so I pass it's address in
//At this point x holds 5
int *p;
get1024HeapMemory(&p);//I want to fill the int* variable, so I pass it's address in
//At this point p holds a memory address where 1024 bytes of memory is allocated on the heap
There are other uses too, like the main() argument of every C program has a pointer to a pointer for argv, where each element holds an array of chars that are the command line options. You must be careful though when you use pointers of pointers to point to 2 dimensional arrays, it's better to use a pointer to a 2 dimensional array instead.
Why it's dangerous?
void test()
{
double **a;
int i1 = sizeof(a[0]);//i1 == 4 == sizeof(double*)
double matrix[ROWS][COLUMNS];
int i2 = sizeof(matrix[0]);//i2 == 240 == COLUMNS * sizeof(double)
}
Here is an example of a pointer to a 2 dimensional array done properly:
int (*myPointerTo2DimArray)[ROWS][COLUMNS]
You can't use a pointer to a 2 dimensional array though if you want to support a variable number of elements for the ROWS and COLUMNS. But when you know before hand you would use a 2 dimensional array.
I like this "real world" code example of pointer to pointer usage, in Git 2.0, commit 7b1004b:
Linus once said:
I actually wish more people understood the really core low-level kind of coding. Not big, complex stuff like the lockless name lookup, but simply good use of pointers-to-pointers etc.
For example, I've seen too many people who delete a singly-linked list entry by keeping track of the "prev" entry, and then to delete the entry, doing something like:
if (prev)
prev->next = entry->next;
else
list_head = entry->next;
and whenever I see code like that, I just go "This person doesn't understand pointers". And it's sadly quite common.
People who understand pointers just use a "pointer to the entry pointer", and initialize that with the address of the list_head. And then as they traverse the list, they can remove the entry without using any conditionals, by just doing a
*pp = entry->next
Applying that simplification lets us lose 7 lines from this function even while adding 2 lines of comment.
- struct combine_diff_path *p, *pprev, *ptmp;
+ struct combine_diff_path *p, **tail = &curr;
Chris points out in the comments to the 2016 video "Linus Torvalds's Double Pointer Problem".
kumar points out in the comments the blog post "Linus on Understanding Pointers", where Grisha Trubetskoy explains:
Imagine you have a linked list defined as:
typedef struct list_entry {
int val;
struct list_entry *next;
} list_entry;
You need to iterate over it from the beginning to end and remove a specific element whose value equals the value of to_remove.
The more obvious way to do this would be:
list_entry *entry = head; /* assuming head exists and is the first entry of the list */
list_entry *prev = NULL;
while (entry) { /* line 4 */
if (entry->val == to_remove) /* this is the one to remove ; line 5 */
if (prev)
prev->next = entry->next; /* remove the entry ; line 7 */
else
head = entry->next; /* special case - first entry ; line 9 */
/* move on to the next entry */
prev = entry;
entry = entry->next;
}
What we are doing above is:
iterating over the list until entry is NULL, which means we’ve reached the end of the list (line 4).
When we come across an entry we want removed (line 5),
we assign the value of current next pointer to the previous one,
thus eliminating the current element (line 7).
There is a special case above - at the beginning of the iteration there is no previous entry (prev is NULL), and so to remove the first entry in the list you have to modify head itself (line 9).
What Linus was saying is that the above code could be simplified by making the previous element a pointer to a pointer rather than just a pointer.
The code then looks like this:
list_entry **pp = &head; /* pointer to a pointer */
list_entry *entry = head;
while (entry) {
if (entry->val == to_remove)
*pp = entry->next;
else
pp = &entry->next;
entry = entry->next;
}
The above code is very similar to the previous variant, but notice how we no longer need to watch for the special case of the first element of the list, since pp is not NULL at the beginning. Simple and clever.
Also, someone in that thread commented that the reason this is better is because *pp = entry->next is atomic. It is most certainly NOT atomic.
The above expression contains two dereference operators (* and ->) and one assignment, and neither of those three things is atomic.
This is a common misconception, but alas pretty much nothing in C should ever be assumed to be atomic (including the ++ and -- operators)!
When covering pointers on a programming course at university, we were given two hints as to how to begin learning about them. The first was to view Pointer Fun With Binky. The second was to think about the Haddocks' Eyes passage from Lewis Carroll's Through the Looking-Glass
“You are sad,” the Knight said in an anxious tone: “Let me sing you a song to comfort you.”
“Is it very long?” Alice asked, for she had heard a good deal of poetry that day.
“It's long,” said the Knight, “but it's very, very beautiful. Everybody that hears me sing it - either it brings the tears to their eyes, or else -”
“Or else what?” said Alice, for the Knight had made a sudden pause.
“Or else it doesn't, you know. The name of the song is called ‘Haddocks' Eyes.’”
“Oh, that's the name of the song, is it?" Alice said, trying to feel interested.
“No, you don't understand,” the Knight said, looking a little vexed. “That's what the name is called. The name really is ‘The Aged Aged Man.’”
“Then I ought to have said ‘That's what the song is called’?” Alice corrected herself.
“No, you oughtn't: that's quite another thing! The song is called ‘Ways And Means’: but that's only what it's called, you know!”
“Well, what is the song, then?” said Alice, who was by this time completely bewildered.
“I was coming to that,” the Knight said. “The song really is ‘A-sitting On A Gate’: and the tune's my own invention.”
Pointers to Pointers
Since we can have pointers to int, and pointers to char, and pointers to any structures we've defined, and in fact pointers to any type in C, it shouldn't come as too much of a surprise that we can have pointers to other pointers.
Consider the below figure and program to understand this concept better.
As per the figure, ptr1 is a single pointer which is having address of variable num.
ptr1 = #
Similarly ptr2 is a pointer to pointer(double pointer) which is having the address of pointer ptr1.
ptr2 = &ptr1;
A pointer which points to another pointer is known as double pointer. In this example ptr2 is a double pointer.
Values from above diagram :
Address of variable num has : 1000
Address of Pointer ptr1 is: 2000
Address of Pointer ptr2 is: 3000
Example:
#include <stdio.h>
int main ()
{
int num = 10;
int *ptr1;
int **ptr2;
// Take the address of var
ptr1 = #
// Take the address of ptr1 using address of operator &
ptr2 = &ptr1;
// Print the value
printf("Value of num = %d\n", num );
printf("Value available at *ptr1 = %d\n", *ptr1 );
printf("Value available at **ptr2 = %d\n", **ptr2);
}
Output:
Value of num = 10
Value available at *ptr1 = 10
Value available at **ptr2 = 10
A pointer-to-a-pointer is used when a reference to a pointer is required. For example, when you wish to modify the value (address pointed to) of a pointer variable declared in a calling function's scope inside a called function.
If you pass a single pointer in as an argument, you will be modifying local copies of the pointer, not the original pointer in the calling scope. With a pointer to a pointer, you modify the latter.
A pointer to a pointer is also called a handle. One usage for it is often when an object can be moved in memory or removed. One is often responsible to lock and unlock the usage of the object so it will not be moved when accessing it.
It's often used in memory restricted environment, ie the Palm OS.
computer.howstuffworks.com Link>>
www.flippinbits.com Link>>
it's a pointer to the pointer's address value. (that's terrible I know)
basically, it lets you pass a pointer to the value of the address of another pointer, so you can modify where another pointer is pointing from a sub function, like:
void changeptr(int** pp)
{
*pp=&someval;
}
You have a variable that contains an address of something. That's a pointer.
Then you have another variable that contains the address of the first variable. That's a pointer to pointer.
A pointer to pointer is, well, a pointer to pointer.
A meaningfull example of someType** is a bidimensional array: you have one array, filled with pointers to other arrays, so when you write
dpointer[5][6]
you access at the array that contains pointers to other arrays in his 5th position, get the pointer (let fpointer his name) and then access the 6th element of the array referenced to that array (so, fpointer[6]).
How it works:
It is a variable that can store another pointer.
When would you use them :
Many uses one of them is if your function wants to construct an array and return it to the caller.
//returns the array of roll nos {11, 12} through paramater
// return value is total number of students
int fun( int **i )
{
int *j;
*i = (int*)malloc ( 2*sizeof(int) );
**i = 11; // e.g., newly allocated memory 0x2000 store 11
j = *i;
j++;
*j = 12; ; // e.g., newly allocated memory 0x2004 store 12
return 2;
}
int main()
{
int *i;
int n = fun( &i ); // hey I don't know how many students are in your class please send all of their roll numbers.
for ( int j=0; j<n; j++ )
printf( "roll no = %d \n", i[j] );
return 0;
}
A 5-minute video explaining how pointers work:
There so many of the useful explanations, but I didnt found just a short description, so..
Basically pointer is address of the variable.
Short summary code:
int a, *p_a;//declaration of normal variable and int pointer variable
a = 56; //simply assign value
p_a = &a; //save address of "a" to pointer variable
*p_a = 15; //override the value of the variable
//print 0xfoo and 15
//- first is address, 2nd is value stored at this address (that is called dereference)
printf("pointer p_a is having value %d and targeting at variable value %d", p_a, *p_a);
Also useful info can be found in topic What means reference and dereference
And I am not so sure, when can be pointers useful, but in common it is necessary to use them when you are doing some manual/dynamic memory allocation- malloc, calloc, etc.
So I hope it will also helps for clarify the problematic :)