1st:
p = (int *)sp VS p = int *sp VS p = int (*sp)
2nd:
(struct node*) malloc(sizeof(struct node)) VS struct node* malloc(sizeof(struct node))
VS struct node (*malloc(sizeof(struct node)))
3rd:
#define cEEP_ABC *((CHAR *)ps8c_PROM( EEP_TEST+0x2B ))
What is the difference for the statement in 1st and 2nd question?
For 3rd question, *((CHAR *)ps8c_PROM( EEP_TEST+0x564 ))
^ ^
| |
| |
| |
---------------- What the purpose for these 2 pointer?
Can the statement change to this form: *(CHAR *ps8c_PROM( EEP_TEST+0x2B )) or *(CHAR (*ps8c_PROM( EEP_TEST+0x2B )))?
1st:
p = (int *)sp; //typecasting sp to int* and storing it in p
p = int *sp; //Declares sp as int* and its value is stored in p
p = int (*sp); //Compilation error
2nd:
(struct node*) malloc(sizeof(struct node)); //Allocates memory equal to size to struct node and returns a pointer to the start
Others: Compilation error.
3rd:
(CHAR *)ps8c_PROM( EEP_TEST+0x564 ) typecasts the return value of the function to char * and the leading * gives the value pointed by that address. So it returns a char.
Related
This question already has an answer here:
Dynamic memory access only works inside function
(1 answer)
Closed 8 months ago.
pointer to a struct
code that can not work
struct node
{
/* data */
int data;
};
void addnode(struct node* n)
{
n = (struct node*)malloc(sizeof(struct node));
printf("value of pointer n = %p",&n);
(*n).data = 9;
}
int main()
{
struct node * n1 = NULL;
addnode(n1);
printf("data is %d\n",n1->data);
}
but the code below is fine
struct node
{
/* data */
int data;
};
void addnode(struct node ** n1)
{
// the address of struct
*n1 = (struct node*)malloc(sizeof(struct node));
printf("address of pointer &n1 = %p\n",&n1);
printf("address of pointer *n1 = %p\n",*n1);
(*n1)->data = 99;
}
int main()
{
struct node * n1 = NULL;
//pass the address of pointer instead of value of it
addnode(&n1);
printf("address of pointer &n1 = %p\n",&n1); // self address
printf("address of pointer *n1 = %p\n",&(*n1)); // the address of struct
printf("data is %d\n",n1->data);
}
what makes me confused is why the indirect pointer as a parameter is working, instead of the direct pointer.
The 'indirect' pointer, as you called it, is actually 'a pointer to your pointer variable'.
If you inspect the value of n1 in your debugger, you will see, in your first example, that it will remain NULL (because you did not assign a new value to it).
In the second example however, you assign a value to the variable by accessing it's address.
Your first code can work too if it looks like this:
struct node
{
/* data */
int data;
};
struct node* addnode()
{
struct node* n = (struct node*)malloc(sizeof(struct node));
printf("value of pointer n = %p",&n);
n->data = 9;
return n;
}
int main()
{
struct node * n1 = NULL;
n1 = addnode();
printf("data is %d\n",n1->data);
}
I supposed to write a long explanation of the code but the explanation is already in the code below so I guess my question is: How do I get it to work without having to malloc then freeing it? or basically what is the correct way to write this in a situation like this?
#include <stdio.h>
#include <malloc.h>
struct d {
int f;
};
struct d* rr() {
struct d* p = malloc(sizeof (struct d*));
p->f = 33;
return p;
}
void rr2(struct d* p) {
p = malloc(sizeof (struct d*));
p->f = 22;
}
int main()
{
//works..
struct d* g;
g = malloc(sizeof (struct d));
g->f = 45;
printf("[%i]", g->f);
//works..
g = rr();
printf("[%i]", g->f);
//below, both are same, except in this first case, g is allocated then freed..
//works..
free(g);
rr2(g);
printf("[%i]", g->f);
//doesn't work..
struct d *q;
rr2(q);
printf("[%i]", q->f);
return 0;
}
For starters in the both functions
struct d* rr() {
struct d* p = malloc(sizeof (struct d*));
p->f = 33;
return p;
}
and
void rr2(struct d* p) {
p = malloc(sizeof (struct d*));
p->f = 22;
}
there is a typo. It seems you mean
struct d* p = malloc(sizeof (struct d));
^^^^^^^^
and
p = malloc(sizeof (struct d));
^^^^^^^^^
or
struct d* p = malloc(sizeof ( *p ));
^^^^^
and
p = malloc(sizeof ( *p) );
^^^^^
As for this function
void rr2(struct d* p) {
p = malloc(sizeof (struct d*));
p->f = 22;
}
then in this call
struct d *q;
rr2(q);
the pointer q is passed to the function by value. So the function deals with a copy of the pointer q. Changing the copy within the function does not reflect on the original pointer q. It stays unchanged.
To make the code working you have to pass the pointer by reference (indirectly through a pointer to it). In this case the function will look like
void rr2(struct d **p) {
*p = malloc(sizeof (struct d ));
( *p )->f = 22;
}
and be called like
rr2( &q );
As for this code snippet
free(g);
rr2(g);
printf("[%i]", g->f);
then it just invokes undefined behavior because in this statement
printf("[%i]", g->f);
there is an access to already freed memory.
This question already has an answer here:
Dynamic memory access only works inside function
(1 answer)
Closed 5 years ago.
I'm probably missing something really important regarding pointers and memory management.
I'm building a doubly linked list. I have a struct Node:
struct Node {
void* data;
nodep prev;
nodep next;
};
with nodep being a typedef for a pointer to such a Node:
typedef struct Node * nodep;
Now I wrote an insertAt() function, which takes a nodep lst which is basically a pointer to the first element in the list, or NULL for the empty list, an int pos, the position at which to insert the element and a void* data, which is the payload of the Node. This is the excerpt my code, where I get an error:
nodep insertAt(nodep lst, int pos, void *data){
nodep new = malloc(sizeof(struct Node));
[...]
new -> data = data;
assert(new != NULL);
printf("memory allocated!\n");
/* insert at last position */
if(pos == -1) {
[...]
/* insert at first position */
} else if (pos == 0) {
if(lst == NULL) {
new -> next = lst;
lst = new;
} else {
[...]
}
/* insert at pos */
} else {
[...]
}
return new;
}
This is how I call insertAt() in my main() function:
int i;
nodep lst = NULL;
insertAt(lst, 0, "test");
When I run my program with valgrind, I get an
Access not within mapped region at adress 0x10
for this line of code:
lst = new;
What I want to do is make the nodep lst point to the nodep new, which then is the first element of the list. I don't really get, why I encounter this error.
Thanks in advance for any help.
Cheers Nick
If you want to modify lst you have to use a double pointer.
I will use int for simplicity
int i;
int* ptr = &i;
func(ptr);
func(int* p){
p = ....; //this won't change ptr!
}
func(&ptr);
func(int** p){
*p = ....; //this will change ptr!
}
In case of a double pointer and sizeof(int) = 4 and sizeof(int*) = 4
--------------- --------------- ---------------
|0x4|0x5|0x6|0x7| |0x0|0x1|0x2|0x3| | | | | |
--------------- --------------- ---------------
0x8 0x9 0xA 0xB 0x4 0x5 0x6 0x7 0x0 0x1 0x2 0x3
address of p address of ptr address of i
*p will give you the address of i.This is the address to which ptr points.That's why with double pointer you change the "outside" pointer.
I am writing a program that is attempting to implement a hash table in C. It has to use a pointer to a pointer as an attribute in a struct data type. Here is the code of the relevant structs.
struct node {
char * data;
struct node * next;
};
struct hashtable {
int size;
struct node ** table;
};
Part one of question:
I have been doing a lot of research to figure out just how pointers to pointers work but I still can't seem to get my head around it. Every example I've found assigns two different pointer names to the first and second pointer. eg
x = 5;
*p = &x;
**q = &p;
What about the case above "struct node ** table;"
Is ** table the same as **q in this case?
What would the values of q , *q and **q be in this case? is q = 5 and then *q and **q work back through the addresses or is **q = 5 and *q and q store the addresses?
Part two of question:
How do I access a pointer to a pointer within another function? Here is the code I have right now.
struct hashtable * hashtable_new(int size){
struct hashtable *newTable;
if ( size < 1 )
{
return NULL;
printf("Its returning Null.");
}
else
{
newTable = malloc(sizeof(struct hashtable));
newTable -> size = size;
newTable -> table = malloc(sizeof(struct node) * size);
int i;
for (i = 0; i < size; i++ )
{
newTable -> table[i] = NULL;
}
fprintf(stderr, "Table has been created.");
return newTable;
}
};
I'm not sure I understand how to access either the pointer or the pointer to a pointer through the -> symbol. Is it "newtable -> table" or "newtable -> -> table" ?
The aim of the table is essentially to be a 2d table, where the list is primarily 1D and can spread to 2D to deal with collisions in the hashing.
End note:
Hopefully I've provided enough information to make contextual sense asking this question. Its my first time asking a question on stackoverflow so feel free to ask me extra question, provide CC or flag any mistakes I've made asking this question.
Thank you!
There are several ways to look at a pointer to a pointer. One way is as you described with
int x = 5;
int *p = &x;
int **q = &p;
After all that, the following are all true:
**q == *p == x == 5
*q == p == &x
q == &p
However, another way to look at a pointer to a pointer is as an array of pointers. For example, assume the declaration:
int *arr[10];
Except when it is the operand of the sizeof or unary & operands, the expression arr will be converted ("decay") from type "10-element array of int *" to "pointer to int *", or int **.
If you want to dynamically allocate an N-element array of pointers to struct node, you would write
struct node **arr = malloc( sizeof *arr * N );
You would use the [] subscript operator to access elements in arr as you would a normal array. Since arr has type struct node **, each arr[i] has type struct node *, so you would access members of the structure like so:
arr[i]->data = "foo"; // use -> when the LHS is a pointer to a struct or union
arr[i]->next = NULL;
struct hashtable allows you to create multiple hashtable instances, each one of which has a size member and an array of struct node * which you allocate at runtime, like so:
struct hashtable h1;
h1.size = 512;
h1.table = calloc( h1.size, sizeof h1.table ); // calloc initializes all elements of
// h1.table to NULL
if ( !h1.table )
{
// calloc call failed, handle as appropriate
}
You'd insert a new element into the table like so:
/**
* Assumes we know that the string data points to is not already in
* the table. hashfunc is a pointer to the hashing function.
*/
void insert( struct hashtable *h, const char *data, size_t (*hashfunc)(const char *))
{
/**
* Create a new table entry. Remember that table is an array of
* *pointers* to struct node, and that each array element is initially
* NULL. We still need to allocate something for that table entry
* to point *to*.
*/
struct node *newNode = malloc( sizeof *newNode );
if ( !newNode )
{
/**
* Memory allocation for new node failed, handle as appropriate
*/
}
newNode->data = malloc( strlen( data ) + 1 );
strcpy( newNode->data, data );
/**
* Get the table index by computing the hash and modding against the
* table size.
*/
size_t idx = hashfunc( data ) % h->size;
/**
* Insert newNode at the head of the list starting at
* h->table[idx]. In reality you'd probably want to insert
* strings in order, but for a toy example this is good enough.
*/
newNode->next = h->table[idx]; // newNode->next points to the previous head of list
h->table[idx] = newNode; // newNode becomes new head of list.
}
When you're done, your hashtable looks something like this:
+---+
h1: | | size
+---+ +---+ +---+---+ +---+---+
| | table ----> | | --> | | | --> | | |
+---+ +---+ +---+---+ +---+---+
| |
+---+ +---+---+
| | --> | | |
+---+ +---+---+ +---+---+ +---+---+
| | --> | | | --> | | | --> | | |
+---+ +---+---+ +---+---+ +---+---+
...
table points to an array of struct node *, each of which may point to an instance of struct node, each of which may point to another instance of struct node. In the picture above, two strings have hashed to table[0],
one to table[2], and three to table[3].
Here's a little program that might help you, it might be worth playing about with pointers for a bit and inspecting them, output addresses etc.
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
char *p1 = "String of text.";
char **p2;
/**
* We can print the avtual address of *p1 and **p2...
*/
fprintf(stdout, "p1 = %p\n", p1);
fprintf(stdout, "p2 = %p\n", p2);
/**
* Now if we point p2 at p1 we can then check what address
* *p2 points at...
*/
p2 = &p1;
fprintf(stdout, "*p2 = %p\n", *p2);
/**
* So if you think about it, *p2 should be the same at p1
* if we print it as a string:
*/
fprintf(stdout, "p1 is %s\n*p2 is %s\n", p1, *p2);
exit(EXIT_FAILURE);
}
Hope this helps.
As for referencing the struct from another function, if you're passing a pointer to that structure you use a single -> to refer to any member of the struct...but you are allocating another struct within your struct - using a pointer.
Say I have
struct one {
char *string;
}
struct two {
struct *one a;
struct one b;
char *whatever;
}
If have a pointer to a struct two:
struct two *t;
And it had its member a allocated a struct one...then I'd reference the members of a using ->
t -> a -> string;
But b isn't a pointer so you would do:
t -> b.string;
We're trying to set the address of a struct to an address we are given but when we print out the address of the struct it seems to not be the same value as the address we are given.
/*a struct to keep block information*/
struct header{
int space;
int free; /* 1 = free space and 0 = full*/
struct header *nextHead;
struct header *prevHead;
};
typedef struct header node;
int myinit(int *array, int size){
int newSize = size;
node * nullPointer;
nullPointer = NULL; //make intermediatry node pointer for some bullshit reason
* (array) = newSize; /*store the size of the malloc at the first address*/
printf("Address : %p\n", &array[0]);
array++;
printf("Address after: %p\n", &array[0]);
/*initial block*/
node *root = (node *)&array; /*store the root at the next address available*/
printf("size of struct %lu\n", sizeof(struct header));
printf("%p\n", root);
root->space = newSize;
root->free = 1;
root->nextHead = nullPointer;
root->prevHead = nullPointer;
}
In the line
node *root = (node *)&array;
You're taking the address of "array" local variable. IOW, you take the address of value that's on the stack, not what you are expecting. You have to modify the function's signature like this:
int mymain(int **myarray, int size);
and modify its definition accordingly. Then, you can write:
node *root = (node *)array;
node *root = (node *)&array;
Here you obtain address of a pointer and cast it to other pointer. You should not do this. Here you must allocate the memory for the node:
node * root = (node *) malloc(sizeof(node));
// or this allocates the memory and puts zeros to it
node * root = (node *) calloc(1, sizeof(node));
Also, you don't need any nodes which points to NULL, you can simply use NULL like this:
node->nextHeader = NULL;
Also, instead of using &array[0], use array in this piece of code.
You will become less confused with pointers if you keep to simple code and understand every line you write. When you have a lot of ampersands and special signs in one line you're probably doing something wrong, train your spider sense for those situations.