Pointer having issue to struct in C programming - c

I am having a problem with pointers.
this is an example of what I want
struct Book
{
char name[10];
int price;
}
int main()
{
struct Book b[10]; //Array of structure variables
struct Book* p; //Pointer of Structure type
p = &b; --- HERE is the ERROR
}
This is the error part
p = &b;

b is an array, which can itself decay into a pointer variable. By writing &b, you actually take the address of that pointer and then you end up with pointer to a pointer. It is enough to just write p = b.

Try this. I have not checked but this should work.
p = b;
now if you want to iterate you array of structure then do this
// Example program
#include <stdio.h>
struct Book
{
char name[10];
int price;
};
int main()
{
struct Book b[10]; //Array of structure variables
struct Book* p; //Pointer of Structure type
p = b;
int i = 0;
for(i = 0 ; i<10; i++)
{
printf("Price : %d\n", (p+i)->price);
}
}

b itself is a pointer. Here you can think of arrays as of pointers. So use p=b instead of p=&b

Related

Assigning int array to a int pointer

I want to assign value of an array to a pointer or need a better way to do the below operation .
I have a structure
struct ver{
int *a;
int *b
int *c;
}
struct Versions{
int ver1[3];
int ver2[3];
int ver3[9];
}
static const Versions versionsinfo[] {
"001234",
{0,18,0},
"000000"
};
static Temp_Data;
Versions * GetVersions() {
Versions * pt = NULL;
memcpy(&Temp_Data,&versionsinfo[1]);
pt = &Temp_Data;
return pt ;
}
struct Versions *pointer;
pointer = GetVersions();
struct ver *newVer;
newVer->a= pointer->ver1;
newVer->b= pointer->ver2;
newVer->c= pointer->ver3;
I want to assign the value of Ver1 to a member of struct ver , either a, b or c.
can anyone please let me know if this is possible in C.
Hope this helps
struct ver
{
int *a;
int *b;
int *c;
};
int Ver1[3] = {1,2,3};
int Ver2[3] = {1,2,3};;
int Ver3[9];
struct ver *newVer;
int main()
{
struct ver newV;/*the memory for struct var is allocated in main */
newVer = (struct ver *)malloc(sizeof(struct ver));/*memory allocated in heap*/
newV.a = Ver1;/*OR newVar.a = &Ver1[0];*/
newV.b = Ver2;
newV.c = Ver3;
printf("newV->a[0] is %d", newV.a[0]);
/*OR*/
newVer->a = Ver1;
newVer->b = Ver2;
newVer->c = Ver3;
printf("\nnewVar->a[1] is %d", newVer->a[1]);
free(newVer);
return 0;
}
Well,
int Ver1[3];
int Ver2[9];
int Ver3[9];
They are initializing arrays of type int. So if you want to get those numbers (which are the sizes of the arrays in the above) you need to do
int Ver1 = 3;
int Ver2 = 9;
int Ver3 = 9;
The allocate some memory for the pointer
struct ver *newVer = malloc(sizeof(newVer));
and then put the values in the struct
newVer[0].a = Ver1;
newVer[0].b = Ver2;
newVer[0].c = Ver3;

how to index struct containing a pointer to pointer for struct which is malloc block

i am created a struct
typedef struct t{
int top;
int value;
}s;
and another structure
typedef struct y{
int top1;
s **p
}z;
z *p1;
created a block by malloc
p1 = (z*) malloc(sizeof(z));
p1->p = (s**) malloc(10 * sizeof(s));
I tried with indexing the s structured block by
p1->p[4]->top;
but i got error. is there a way to index pointer to pointer type in C
Address them with single pointer.
typedef struct y{
int top1;
s *p; //Single pointer only
}z;
z *p1;
p1 = malloc(sizeof(z)); //Don't cast...
p1->p = malloc(10 * sizeof(s));
//And then:
p1->p[4].top;
If you still want double pointers, then:
typedef struct y{
int top1;
s **p;
} z;
z *p1;
size_t i;
p1 = malloc(sizeof(z)); //Create z structure object
p1->p = malloc(10 * sizeof(*p1->p)); //Create array of pointers to objects
//Now fill that array with your objects
for (i = 0; i < 10; i++) {
p1->p[i] = malloc(sizeof(*p1->p[i]));
}
//Now access to property as:
p1->p[4]->top; //Do something.
The second option is less preferable but depends on you, because doing single mallocfor 10 objects in a row is more efficient than doing 10x times single object and 11th time for initializing base array of pointers.
In struct y{ ...; s **p }, member p represents a pointer to a pointer to structure s, and not a pointer to structure s.
So p1->p[4] is a pointer to an s, not an s itself, so you cannot access member top with accessor .. To get around the compiler error, you would have to use accessor ->, which dereferences the pointer value, but then you yield undefined behaviour at runtime, since the pointer value is not initialized.
To solve the problem, you could either change the data type of p to s *p (as suggested by #tilz0R), or you could adapt your code to actually deal with pointers to pointers:
typedef struct t{
int top;
int value;
}s;
typedef struct y{
int top1;
s **p;
}z;
z *p1;
int main() {
p1 = malloc(sizeof(z));
p1->p = malloc(10 * sizeof(s*));
for (int i=0; i<10; i++) {
p1->p[i] = malloc(sizeof(s));
}
p1->p[4]->top = 5;
}
Note that pointers to pointers are more complicated to handle, as you need an extra step/loop to initialize the pointers and to free them later on. So actually I'd prefer the s *p-way; But sometimes pointers to pointers are more appropriate, e.g. if particular slots of the array shall remain "empty"; then you could set the respective pointer to NULL, which would not be possible in an array of struct objects.

Trying to set a pointer to a struct

I have a function called SemCreate that takes a name an int and a pointer as parameters. I want the pointer to point to a new struct and I want to return an int, 0 if it went okay.
int P1_SemCreate(char *name, unsigned int value, P1_Semaphore *sem){
USLOSS_Console("Create a semaphore\n");
if(!verifyKernel()) {
//USLOSS_Console("ERROR: Not currently in Kernel mode\n");
USLOSS_Halt(1);
}
if(numSems>= P1_MAXSEM){
//USLOSS_Console("ERROR: MAX semaphore already exist\n");
return -2;
}
if(name == NULL){
return -3;
}
interruptsOff();
int i;
for (i = 0; i < P1_MAXSEM; i++) {
if (semTable[i].inUse == 0) {
semTable[i].value = value;
semTable[i].list = NULL;
semTable[i].name = malloc(sizeof(char));
strcpy(semTable[i].name, name);
semTable[i].inUse = 1;
semaphore *temp = NULL;
temp = malloc(sizeof(semaphore));
temp->value = value;
temp->list = NULL;
temp->name = malloc(sizeof(char));
strcpy(temp->name, name);
*sem = temp;
break;
}
}
numSems++;
interruptsOn();
return 0;
}
Right now the pointer is fine within the function but once I return the pointer is null
EDIT: The array semTable is an array of semaphores
typedef struct semaphore{
int value;
char * name;
struct node *list;
int checkPoint;
int inUse;
}semaphore;
typedef struct PCB {
USLOSS_Context context;
int (*startFunc)(void *); /* Starting function */
void *startArg; /* Arg to starting function */
int pid;
int status;
int killedStatus;
int state;
int priority;
char name[50];
int parentPID;
int numOfChild;
int blockFlag;
struct sempahore *blockSem;
char *stack;
struct node *children;
struct node *zombiList;
int cpuTime;
int startTime;
struct semaphore *childSem;
} PCB;
typedef struct node {
PCB *pcb;
struct node *next;
} Node;
Your question is not perfectly clear as to what you are trying to do. So, this answer addresses the following general topics in hopes they will assist:
1) Passing the address of a struct via a function, changing the values of the struct members, and accessing changed values in calling function. (It is not the same as the one you show, but illustrates what you want to do.)
2) Creating instances and pointers to instances of a struct, then initializing.
3) Contains link to tutorial on self referencing structs. (as you are doing in your posted code)
typedef struct {//struct definition created in global space, typedef'ed
char line[80]; //to read in the line
int slot;
char type[20]; //long enough for any types listed
int position;
}SLOT;
int modifyStruct(SLOT *slot);//prototype of demonstration function
int main(void)
{
SLOT s;//create instance of SLOT local to main
int ret = modifyStruct(&s);pass address of SLOT instance to change member values
printf("Line: %s\n", s.line);//show changed values
printf("Slot: %d\n", s.slot);
printf("type: %s\n", s.type);
printf("position: %s\n", s.position);
return 0;
}
int modifyStruct(SLOT *slot)
{
strcpy(slot->line, "lineA");
slot->slot = 2;
strcpy(slot->type, "large");
slot->position = 20;
return 0;
}
EDIT - To address question in comment asking how to set a struct pointer to point to a struct.
First, it appears from viewing the code you have posted, that you are using self referencing structs. (i.e. a struct that contains a member that is a pointer instance to itself) Here is a link to a good tutorial dealing with Linked Lists in C, which use self referencing structs.
Regarding you comment: _I guess I should have made it more clear. P1_Semaphore is different to semaphore. I need P1_semaphore to point to the semaphore_.:
If P1_Semaphore is different than semaphore, then one should not be set to point to the address of the other. And your compiler will not let you do that anyway.
As I stated in the comments, a struct pointer should only point to a place in memory that contains an instance of that struct. For example consider the two structs A & B:
typedef struct {
int iNum;
float fNum;
char cStr[80];
}A;
A a, *pA; //create an instance, and pointer to an instance of A
typedef struct {
int iNum1;
int iNum2;
int iNum3;
}B;
B b, *pB; //create an instance, and pointer to an instance of B
A & B are obviously different, and will occupy a different size and shape in memory, so if the pointer to B, *pB was set to point to anything but B, it would be incorrect. It needs to point to B
Correct:
pA = &a //set pointer to A equal to the address of A
pB = &b //set pointer to B equal to the address of B
Incorrect:
pA = &b //set pointer to A equal to the address of B
pB = &a //set pointer to B equal to the address of A
(typical compiler error - Operands of = have types pointer to B and pointer to A)
In C/C++, all parameters are passed by value, not by reference. To get the struct pointer in parameter, you need to use pointer to pointer as the parameter. Like this:
int P1_SemCreate(char *name, unsigned int value, P1_Semaphore **sem){
...
*sem = temp;
...
}

malloc of array in struct passed as argument

I would like to allocate memory for arrays that are members of a struct I need to use, inside a function that takes the struct as an argument.
arg->A.size=(int*) malloc(N*sizeof(int));
will not compile (request for member 'size' is something not a structure.
arg->A->size=(int*) malloc(N*sizeof(int));
will throw a segmentation fault error
Any help will be appreciated.
Here is the code, thanks:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// struct A
struct A {
int dim; // dimensions
int* size; // points per dim array
double* val; // values stored in array
int total; // pow(size,dim)
};
// struct B that uses A
struct B {
int tag;
struct A* A;
};
int function_AB(struct B* B);
int main(void){
struct B B;
function_AB(&B);
return 0;
}
int function_AB(struct B* arg){
int N=10;
arg->tag=99;
printf("tag assigned = %d \n", arg->tag);
arg->A->size=(int*) malloc(N*sizeof(int));
return 0;
}
You simply haven't allocated memory for struct A *A. Before assigning anything to A->size you would first need to do something like
B->A = malloc(sizeof(struct A));
The second case is correct, but crashes because the A inside the B declared in main has not been assigned a value. You probably want something like
struct A A;
struct B B;
B.A = &A;
function_AB(&B);
When you have structure pointer in another structure, first you need to allocate memory for that. then allocate the memory for structure members!
struct B {
int tag;
struct A* A;
};
Here A is a pointer to a structure called A. First allocate memory for this, then allocate memory for the elements of struct A
arg->A = malloc(sizeof(struct A));
then do-
arg->A->size = malloc(N*sizeof(int));
Try the following changes in your int function_AB(struct B* arg)-
int function_AB(struct B* arg){
int N=10;
arg->tag=99;
printf("tag assigned = %d \n", arg->tag);
arg->A = malloc(sizeof(struct A)); // First allocate the memory for struct A* A;
arg->A->size = malloc(N*sizeof(int)); // Allocate the memory for struct A members
arg->A->val = malloc(N*sizeof(double));
// do your stuff
// free the allocated memories here
free(arg->A->size);
free(arg->A->val);
free(arg->A);
return 0;
}
And don't cast the result of malloc()!

Strings and structures in c

#include "stdafx.h"
#include <stdio.h>
struct s
{
char *st;
struct s *sp;
};
struct s *p1,*p2;
void swap(struct s *p1,struct s *p2);
int main()
{
int i;
struct s *p[3];
static struct s a[]={
{"abc",a+1},{"def",a+2},{"ghi",a}
};
for(i=0;i<3;i++)
{
p[i]=a[i].sp;
}
swap(*p,a);
printf("%s %s %s\n",p[0]->st,(*p)->st,(*p)->sp->st);
return 0;
}
void swap(struct s *p1,struct s *p2)
{
char *temp;
temp = p1->st;
p1->st = p2->st;
p2->st = temp;
}
This program outputs as abc,abc,ghi. My doubt is what does p[0]->st,(*p)->st,(*p)->sp->st outputs.we havent intialised st with abc or ghi.How does it outputs the string?
We havent intialised st with abc or ghi. How does it outputs the
string?
The value of the st member for each structure in the statically allocated array a is actually initialized through an initialization list. Writing
static struct s a[]={
{"abc",a+1},{"def",a+2},{"ghi",a}
};
has the same effective meaning after its execution as writing the following:
static struct s a[3];
a[0].st = "abc";
a[0].sp = a+1;
a[1].st = "def";
a[1].sp = a+2;
a[2].st = "ghi";
a[2].sp = a;
And what's effectively happened after both methods of initialization is you have a statically-allocated circular linked list of struct s, where the data-members of each node in the list (the st member) is pointing to a string literal like "abc", "def", etc. The sp data member is pointing to the next node in the linked list.
I haven't analysed all the statements, but assignment to ->st and ->sp happens here:
static struct s a[]={
{"abc",a+1},{"def",a+2},{"ghi",a}
};
the rest are games with pointers so the output is what you see. So, say:
the a array is created and initialized;
in the for loop the p array is also initialized;
noticing that sp recursively points to struct s instances, p and a have the same structure;
each elements of p is made point to a struct s instance taken from one of the elements of a.

Resources