I'm basically trying to create an array of struct pointers. Each of these pointers is supposed to point to another element of the same structure array i.e BLOCKS[2].
This is what I've done so far.
typedef struct bb {
..
..
..
struct bb **successor;
} BLOCK;
BLOCK BLOCKS[10];
struct bb **A = malloc(sizeof(struct bb*)*5); //create an array of pointers of type struct bb, 5 units i.e A[0]->A[4].
BLOCKS[0].successors = A //just assigning
Now......how do I assign the first element of the pointer array, A, to another structure?
I tried:
A[0] = &BLOCKS[6];
It compiles fine but I get a seg fault.
Have you tried this one:
typedef struct bb {
..
..
..
struct bb *successor;
} BLOCK;
BLOCK BLOCKS[10];
struct bb *A = malloc(sizeof(struct bb)*5); //create an array of pointers of
type struct bb, 5 units i.e A[0]->A[4].
BLOCKS[0].successors = A[0];
Because after looking at it quickly I think the ** should render into * and your malloc is reserving memory not for the size of 5 structures but the size of 5 pointers to this structure.
Quote from Question: "I'm basically trying to create an array of struct pointers."
The array of structure pointer should be
BLOCK *ptrBlockArr[10]; //This an array of size 10, which can store 10 pointers to the structure BLOCK
Now, since, these are pointers, you will have allocated memory for each of the elements. This should be done like
for(int i=0; i<10; i++)
{
ptrBlockArr[i] = (BLOCK *)malloc(sizeof(BLOCK));
}
You question also included: "Each of these pointers is supposed to point to another element of the same structure array" . This can be done like
for(int i=0; i<9; i++) // Run the loop till the last but one element
{
ptrBlockArr[i]->successor = ptrBlockArr[i+1];
}
//Assign the last's element's sucessor as the first element. This will make it circular. Check if this is your intention
ptrBlockArr[9]->successor = ptrBlockArr[0]
Please note that in your structure successor is struct bb**, whereas it should be struct bb*.
Also, you can optimize the code to combine the two loops shown by me above into one loop. I'll leave that to you to learn by yourself and implement.
Related
I have a problem with lists and pointers, let me explain.
let's define a list like this:
typedef struct list *LIST;
typedef struct node *link;
struct list{link head; int n;};
struct node{Item val;link next;};
where n is the number of nodes and LIST is a pointer to struct list (I have to do that because I want to make an opaque pointer to the list, in my homework the LIST pointer would go in the .h and the structs would go in the .c but that's not the problem, and I know I should avoid declaring pointer like that).
The Item type is also declared via an opaque pointer, so I have something like this:
typedef struct info *Item;
struct info{char *name;int N};
my problem is that I don't understand how to insert stuff in this lists. (so I would like to add an Item type to the lists, but I can't because Item is a pointer so, for example if a try to do this:
//the lists is already initialized and let's say we want to add 3 nodes
Item x=malloc(sizeof(*x));`
x->name=calloc(10,sizeof(char));
for(int i=0;i<3;i++){
fscanf("%s",x->name);
fscanf("%d",x->N);//this is a random number
ListInsert(L,x);
}
this is what i have in ListInsert():
void ListInsert(LIST L, Item x){
link z,p;
if(L->head==NULL)
L->head=newNode(x,L->head);
else{
for(z=L->head->next, p=L->head;z!=NULL;p=x, z=z->next);//i know a tail would help
p->next=newNode(x,z);
}
}
And this is what I have in newNode():
link newNode(item x,link next){
link z=malloc(sizeof(*z));//should control the allocation was successful I know
z->val=x;
z->next=next;
return z;
}
Whenever I modify the value x, I'm actually modifying what the head and everything points to, that's my problem, what could be a solution? maybe make an array? pointers can sometimes be so hard to understand, for example should I allocate z->val->name?
When you say ...
Whenever I modify the value x, I'm actually modifying what the head and everything points to, that's my problem, what could be a solution?
... I think you're talking about this code:
Item x=malloc(sizeof(*x));`
x->name=calloc(10,sizeof(char));
for(int i=0;i<3;i++){
fscanf("%s",x->name);
fscanf("%d",x->N);//this is a random number
ListInsert(L,x);
}
Indeed, you have allocated only one struct info and assigned x to point to it. You have added that one struct info to your linked list three times, and also modified it several times.
Supposing that your objective is to add three distinct objects to the list, the solution starts with allocating three distinct objects (else where would they come from?). Since each one has a pointer to a dynamically allocated array, you will also want to allocate a separate array for each of those. The easiest way to achieve that would be simply to move the allocations into the loop:
for (int i = 0; i < 3; i++) {
Item x = malloc(sizeof(*x));
x->name = calloc(10, sizeof(char));
fscanf("%s", x->name);
fscanf("%d", x->N); //this is a random number
ListInsert(L, x);
}
If you are permitted to modify the structures involved then you could also consider making the name element of struct info an array of suitable length instead of a pointer. That's a little less flexible, but it would mean that you need only one allocation for each item, not two.
I am struggling with the free of memory working with dynamic arrays. Considering the following code:
struct element{
float a;
float b;
};
struct list{
int size;
struct element *myelements;
};
int main(){
struct list mylist;
mylist.size = 0;
mylist.myelements = (struct element*) malloc(sizeof(struct element)*4); //I reserve it as if i had struct element myelements[4]
//i do stuff like
int i;
for(i = 0; i< 4 ; i++){
mylist.myelements[i].a = i;
mylist.myelements[i].b = i*2;
}
//I try to free myelements[2] for example, but i get an error
free(mylist.mylements[3]);
return 0;
}
My question is, how am i supposed to free the second possition of my array of elements. I have thought some alternatives involving realloc:
mylist.mybooks = realloc(mylist.mybooks, sizeof(mylist.mybooks) - sizeof(struct element));
but in that case wouldn´t I have to reorder the elements of the array?
Thanks in advance!
My question is, how am i supposed to free the second possition of my array of elements.
free deallocates the entire allocation done by malloc, it cannot deallocate a part of one allocation.
A common way to manage a resizeable array is to maintain its capacity and size, and when removing elements move subsequent array elements to fill the removed element gap and reduce the size. The spare capacity is used for new elements when they get inserted. Calling realloc for every element insertion/removal is sub-optimal in terms of speed.
This is a structure that I am using:
struct nodeList//a node structure
{
int jump;
int config;
int level;
int shifts[200];
int shift_diff[200];
struct nodeList *next;
};
I want to create a 2D array of pointers that can be used to reference such a structure variable, ie, any element of that array can be assigned a pointer to a structure variable. I would prefer to create the array dynamically using malloc, if possible. Any pointers (pun unintended) would be appreciated.
First of all, please think twice about the program design. Do you really need a 2D array of pointers, each pointing to a struct, each struct containing a number of items? Those requirements are rather complex: if you can simplify them, your program will turn out much better.
Because with the current requirements, you'll notice that the pointer and array syntax will turn quite complex, which the requirements are to blame for, more so than the C language.
Consider things like using a 2D array of structs, or to use some sort of pointer-based ADT which makes sense for your given case (linked list, queue, graph, binary tree? etc etc).
That being said, a 2D array of pointers to struct:
struct nodelist* array[X][Y];
To allocate this dynamically, you need a pointer to a 2D array of pointers to struct:
struct nodelist* (*array_ptr)[X][Y];
Then assign this to a 2D array of pointers to struct, allocated dynamically:
array_ptr = malloc( sizeof(struct nodelist*[X][Y]) );
...
free(array_ptr);
Note that unless the 2D array is not allocated like above, in adjacent memory cells, it is not an array.
EDIT. Btw, if you wish to avoid the weird syntax that an array pointer will yield, there is a trick. With the code above you will have to address the array as
(*array_ptr)[i][j];
Meaning: "in the 2D array, give me item number [i][j]".
Had you omitted the inner-most dimension of the type, you could simplify this syntax:
struct nodelist* (*array_ptr)[Y]; // pointer to a 1D array
The malloc will be the same but you can now use it like this instead, which may be more intuitive:
array_ptr[i][j];
Meaning: "in array number i, give me item number j". You are here assuming there is an array of arrays in adjacent memory, which is true.
NODELIST ***pppNode, Node;
size_t Row = 5, Col = 5, i;
pppNode = malloc( sizeof(NODELIST **) * Row );
for(i = 0; i < Row; i++)
pppNode[i] = malloc( sizeof(NODELIST *) * Col );
pppNode[1][0] = &Node;
This is another way of dynamic allocation but as #Lundin said if it is not necessary change the design.
I am attempting to develop a dynamically-allocated circular-buffer in C using two structs. One holds detailed information and another is essentially used as a pointer from main to the circular-buffer structure (as there will be multiple arrays allocated at runtime).
Since it is a circular-buffer, I have a pointer "next" which points to the next item in the array (so last array index points to the first, etc.)
These are the two struct objects I have:
typedef struct {
int a;
int b;
struct1 *next; // pointer to next struct1 object in array
} struct1;
typedef struct {
struct1 *curr;
struct1 *start = NULL;
struct1 *end = NULL;
} struct2;
I then have my initialize function that is called from main to initiate a new circular-buffer.
This is the part where I am not entirely sure what to do.
#define minSize 10
struct2 * initialize()
{
struct2 **newBuf = malloc(sizeof(*newBuf));
newBuf->malloc(sizeof(*newBuf->quotes) * newBuf->minSize);
// set the start pointer
newBuf.curr[0] = newBuf->start;
newBuf.curr[0]->next = NULL;
for (int i = 1; i < minSize; i++)
{
struct1 *new = NULL;
newBuf.curr[i] = new; // make index i = NULL
// have the previous index point to the "next" current
if (i > 0)
newBuf.curr[i-1]->next = newBuf.curr[i];
}
// connect last index with first
newBuf.curr[minSize - 1]->next = newBuf.curr[0];
// set the end pointer
newBuf->end = newBuf->start;
return newBuf;
}
From searching I found this answer on how to initialize an array of structs within a struct by using malloc for initially allocating the space, but am confused how my code would line up since I have pointers to define start and end of the circular-buffer defined in struct2, as well as the next pointer as part of struct1.
Additionally, I've chosen to define ***newBuf* instead of **newBuf* as I was considering it as a pointer to pointers in a way (thinking about singly-linked lists). Though, please correct me if I am wrong.
I've done dynamically allocated circular-buffers in Java, but not C nor C++, so I am having a hard time figuring out the differences in how to initialize everything. I'm basically stuck at this mess and not sure where to go next.
Any help that can be given would be much appreciated!
The reason you're running into trouble is because you're trying to have the pointer to a pointer, rather than just using an ordinary pointer. You want to access the pointer that is contained at the address pointed to by the first pointer. As it stands you're trying to access a member that is outside of the memory space of the original pointer's address (which is only as large as an address). And then you're running into trouble because you aren't initializing your array 'curr' either. Another thing I did that doesn't really matter but helps you understand pointers is made your array a pointer- which is how arrays work in C. The array is simply the address of the first member of the array, and when you index into the array, it just adds an offset to that address = index * sizeof(yourstruct).
What you want is
typedef struct {
struct1 *curr;
struct1 *start = NULL;
struct1 *end = NULL;
} struct2;
#define minSize 10
struct2* initialize()
{
struct2 *newBuf = (struct2 *) malloc(sizeof(struct2));
newBuf->curr = (struct1 *) malloc(sizeof(struct1) * minSize);
// set the start pointer
newBuf.curr[0] = newBuf->start;
newBuf.curr[0]->next = NULL;
for (int i = 1; i < minSize; i++)
{
struct1 *new = (struct1 *) malloc(sizeof(struct1));
newBuf.curr[i] = new;
newBuf.curr[i-1]->next = newBuf.curr[i];
}
// connect last index with first
newBuf.curr[minSize - 1]->next = newBuf.curr[0];
// set the end pointer
newBuf->end = newBuf->start;
return newBuf;
}
I have been at this problem for the last 6 hours and have been hitting google like mad to no avail.
Right I need a pointer to an array. This array contains pointers to Linked lists. Im going to have to malloc it since I dont know the array size until runtime.
LList **array
This was my first thought but this just gives me a pointer to an array of LList. Or atleast that is my understanding. Can someone give me a hand?
EDIT: Some info on how it would be used: I am implementing a very basic hash table. There is a structure that contains a pointer to an array of pointers to linked lists.
It needs to be a pointer to the array so that when I resize the table. I can just change the pointer to point to the larger table.
It sounds like you're on the right track.
LList **array;
array = malloc(num_ptrs * sizeof(LList*));
array is now an array of pointers to LList, and elements such as array[3] will be a pointer to a LList.
Arrays and pointers are very similar in C (but not identical!), as shown by the classic example: *(array + 2) is mostly equivalent to array[2].
Edit:
When you need to resize the table, you'll just need to realloc the additional space:
LList **new_array;
new_array = realloc(old_array, new_size * sizeof(LList*));
new_array and old_array may or may not be the same pointer afterwards, but either way new_array is guaranteed to be a pointer to enough space to hold the new array (or NULL if the memory couldn't be allocated)
2nd Edit:
As user411313 alluded, if you want the actual pointer to the array, you'll need to take the address of the array:
LList ***p_array;
p_array = &array;
A pointer to an object, is basically the same as a pointer to an array.
int * blah; // an int pointer. It could point to an array of ints, or a single int.
int ** blah; // a pointer to an int pointer. It could point to something that points to an int, or it could be pointing to an array of pointers to single ints, or it could be a pointer that points to an array of ints.
It all depends on how you use it.
A pointer to a pointer can also be an array of pointers.
int nLists; /* number of lists*/
LList **array;
array = (LList **)malloc(nLists * sizeof(LList *));
will make array be an array of pointers to LList. Then array[i] will give you the pointer to the i-th linked list in the array.
if you have to write your own linked list, you can do this.
typedef struct LLNode {
LLNode* next;
int data;
} LLNode;
LLNode* linkedList = null; // a linked list
LLNode** linkedListArray = (LLNode**) malloc( arraySize* sizeof(LLNode*) );
LLNode*** pointerToLListArray = &linkedListArray;
with a linked list library:
LList* linkedListArray = (LList*) malloc( arraySize* sizeof(LList) );
LList** pointerToLListArray = &linkedListArray;
typedef struct LList LList;
struct LList {
int value;
LList *next; };
LList *(*p)[3]; /* pointer to an array of 3 pointers to LList */
LList ll1 = {11};
LList ll2 = {22};
LList ll3 = {33};
size_t sizeofarray = sizeof*p/sizeof**p; /* calc arraysize at runtime here */
p = malloc( sizeofarray * sizeof**p ); /* allocate space for each LList-pointer in array */
(*p)[0] = &ll1;
(*p)[1] = &ll2;
(*p)[2] = &ll3;
/* test output here: */
printf("\n%d\n%d\n%d", ((*p)[0])->value,((*p)[1])->value,((*p)[2])->value);
free(p);