Accessing members in a pointer to a pointer of a struct - c

Code is as follows:
/* set.h */
struct setElement{
char *element;
setElement *next;
};
typedef struct setElement *Set; //Set is now the equivalent of setElement*
Set a;
setInit(&a);
/* setInit function declaration # setInit.c */
int setInit(Set *a){
(*a)->element = "asdf"; //results in a seg fault
}
Trying to malloc 'a' works, but if I try to access any member within the set 'a' doesn't work. I understand I'm passing a reference of the set from the main() function to setInit, so I believe the pointer contained within setInit is addressing the memory allocated by 'Set a' in the main() function, so a malloc wouldn't be required...
Iunno. Help is appreciated :)

The problem is that you have not allocated the setElement you are trying to assign to. In the main part of the code you are creating a Set, which is just a pointer to a setElement. This pointer is never set to point to anything sensible. I.e. you need something like
Set a = malloc(sizeof(setElement));

Alas, it is unclear where exactly your variables are defined. I assume your main.c is something like
#include "set.h"
Set a;
int main()
{
setInit(&a);
}
If so, your a, which is a pointer by itself, should point to somewhere.
If your framework wants malloc()ed data, you should do
int main()
{
a = malloc(sizeof(*a)); // *a is a struct setElement now, with 2 pointer-sized members.
setInit(&a); // Now seInit should be able to operate on the struct as wanted.
}

As #amaurea has mentioned, you'll need to make use of malloc() for your setElement structure. In addition to this, you need to do the same for the setElement struct's element member. A char* is merely a pointer to a char or char array and will not implicitly allocate anything.
int setInit(Set *a){
(*a)->element = "asdf"; //results in a seg fault
}
Could be re-written
int setInit(Set *a){
(*a)->element = malloc(sizeof("asdf"));
strcpy((*a)->element,"asdf");
}
Which the above could be rewritten to take a second parameter of the actual element contents.

Related

How to modify pointer to structure inside void function

I tried to google my problem many times but never found an answer that fits my problem. I have to modify a pointer to a structure inside a function(fill it with data), and then use that pointer as an argument to another functions.
I have a text file that has multiple reports in it and I am supposed to count the reports and fill all the data to a pointer to a structure. Which isnt a problem, I allocated memory without a problem, got through the file without a problem and also filled the pointer. But I can't figure out how to use the filled pointer outside of the function.
struct report{
char name[50];
int id_number;
}
void function1(struct report **ptr){
//do stuff like count the number of reports in file
//and allocate memmory for pointer to structure
//and fill the pointer to structure with data
}
int main() {
struct report *pointer;
function(pointer);
//now I expect variable 'pointer' to be filled and ready to use by another functions
return 0;
}
Can you please suggest some solutions please? Thank you for your time and help.
Please have a look at the example:
#include <stdlib.h>
#include <stdio.h>
struct report{
char name[50];
int id_number;
};
void foo(struct report **ptr){
*ptr = malloc(sizeof(struct report)); // allocate memory
(*ptr)->id_number = 42; // fill the allocated memory
}
int main() {
struct report *pointer;
foo(&pointer); // important part - pass to the foo() pointer to the pointer.
printf("%d\n", pointer->id_number);
free(pointer); // do not forget to free the memory.
return 0;
}

using strcpy to copy a string to a member of a structure via the pointer operator

I'm trying to use strcpy to set values for a char array which is the member of a structure. I want to do this using the pointer operator if possible.
struct my_struct{
char foo[15];
} *a_struct_Ptr;
int main(){
strcpy(a_struct_Ptr -> foo, "test");
return 0;
}
I can compile this code but when I go to run it I get a segmentation fault.
Also it seems to work fine if I don't define the struct as a pointer, for example the following code works fine...
struct my_struct{
char foo[15];
}a_struct;
int main(){
strcpy(a_struct.foo, "test");
return 0;
}
I want to be able to do this with pointers though.
Any feedback is appreciated. Thanks
The problem as many commented, was that I didn't allocate memory for the pointer to my structure.
By preceding my strcpy statement with
a_struct_Ptr = (struct my_struct *) malloc(sizeof(struct my_struct));
I was able to successfully copy a string literal to the char array member of my_struct.
As is good practice, I added free(a_struct_Ptr); after the struct is done being used.

Questions about a college project

I have
the struct:
typedef struct Rental {
int nDays;
float kmsDriven;
char carLicensePlate[LICENSE_PLATE_LENGTH+1];
char *clientName;
char chargingCategory;
} Rental;
Different -Rental type- structs are stored and accessed via a dynamically allocated array of pointers (here is a part of the project):
int main (){
Rental *rentals;
int max_num;
printf("Give a number of rentals you would like to store and manage: ");
scanf("%d", &max_num);
rentals=(Rentals *)malloc(max_num * (sizeof(Rental)))
This is what I have thought of so far but I can't understand it completely...so:
I'm having trouble understanding how *rentals can be an array. I mean shouldn't I declare it at least this way: Rental *rentals[];? I know that if I compile the above code I will see an error...but why?
I've read numerous posts here in Stack Overflow about doing this with double pointers (Rental **rentals;) but the code other people have posted is often very hard for me to read (I don't know all the functions etc. etc.)
Let's say I have the object rentals[0] which will be a pointer towards rentals. If I wanted to pass the struct to a function, should I write:
variable=function(*arguments*... , Rental *rentals[0]);?
rentals is a pointer, not an array, but it is a pointer to the first (zeroth) element of a block of max_num structures, so it can be treated as an array in that you can use rentals[n] to refer to the nth element of the array.
This is not a question and hence it is unanswerable.
Let's say I have the object rentals[0] which will be a pointer towards rentals. If I wanted to pass the struct to a function, should I write: variable=function(*arguments*... , Rental *rentals[0]);?
rentals[0] is not a pointer; it is a struct Rental or Rental.
If you want to pass the structure to the function, you write:
variable = function(…args…, rentals[0]);
If you want to pass a pointer to the structure to the function, you write:
variable = function(…args…, &rentals[0]);
or:
variable = function(…args…, rentals);
These pass the same address to the function.
You should be error checking the call to scanf() to make sure you got a number, and you should error check the number you got (it should be strictly positive, not zero or negative), and you should error check the value returned by malloc().
When you declare an array (for example char buffer[10]; the variable is actually pointing to that array. Pointers and arrays are very close together. In fact when you have a pointer where you store an array of data (just like your case with malloc) you can do something like pointer[0] and pointer[1] to get the correct element.
With a pointer in order to access an element you'd normally use *(pointer +1) to get the element on position 1, this is exactly the same as pointer[1].
When you want to pass a struct in an array, you can either give it by value like this:
void function(struct mystruct var)
{
//...
}
int main()
{
struct mystruct var;
function(var);
}
Or by reference (passing the address instead of the data - this is ideal if your structs are big in size) :
void function(struct mystruct *var)
{
//...
}
int main()
{
struct mystruct var;
function(&var);
}
By using an array, you can do it like this (still by reference):
void function(struct mystruct *var)
{
//...
}
int main()
{
struct mystruct var[10];
function(&var[0]);
}
And using a pointer (to an array) :
void function(struct mystruct *var)
{
//...
}
int main()
{
struct mystruct *var;
var = malloc( sizeof(struct mystruct) *10 );
//This will pass the address of the whole array (from position 0)
function(&var);
//This will pass the address of the selected element
function(&var[0]);
}
As you can see, declaring an array or a pointer is almost the same, expect that you have to initialize the pointer-array yourself (with malloc) and as with anything created with malloc you have to free it yourself too.

Passing a structure pointer as a function argument (Seg fault unknown)

Header file #1 "city.h"
typedef struct City{
double* lat;
double* lon;
double* pop;
char* airport;
char* name;
}City;
Header file #2 "vector.h"
typedef struct Vector{
City* cityArray[26]; // 26 pointers to struct City
}Vector;
C file
#include "vector.h"
#include "city.h"
#include <stdlib.h>
void init(Vector *ptr) {
ptr->cityArray[0]->name = "hi"; // Error Seg Fault!
}
Hi, Your suggestion did work, but for some reason I'm getting Seg faults now even though the I'm 100% sure the code didn't change. Could you see whats wrong?
Try this -
ptr->cityArray[0]->name = "hi"; // ptr is pointer to struct vector
As cityArray is a member variable of struct Vector , access it using a struct variable or pointer .
Can't do this
cityArray[0]->name = "hi";because cityArray is not any independent array of pointers.
EDIT
As you get segmentation fault , you need to allocate memory to struct pointer ptr as well as to char * present in struct city.
In function do it like this -
ptr=malloc(sizeof(Vector));
ptr->cityArray[0]->name=malloc(3); // size 3 to store "hi" you can give desired size.
But remember to free allocated memory.
In your case, vector.h appears before city.h. You need to put city.h before vector.h to make the definition of city visible to vector.
That said, cityArray itself is not an independent variable, it is called a member variable. You need to have a variable of the structure type to make use of cityArray. Something like
Vector Vec;
Vec.cityArray[0]->name ....
and so on. Also make a note about the type of the variable and the initializer used. They both should match.

Unable to assign values in a structure

I have declared the structure:
typedef struct keyValuePairs{
char* type;
char* key;
char* valueType;
char* value;
} keyValueType;
keyValueType keyValuePairs[1000];
And in a function declared the local variables as:
char key[500];
char value[500];
to hold the key value pair values as:
key[i]="abc";
value[i]="xyz"
I have assigned these local variables to the global variable as:
keyValuepairs[1].key=key.
Once i come out of the function, the values assigned in the structure is getting lost. Can someone explain where I am going wrong?
Please note I am fairly new to C.
Both key and value variables are pointers to arrays that are allocated in the stack when you are in the function. After keyValuepairs[1].key=key the global variable points to that same place in the stack. After exiting the function, the memory where those arrays were is reused.
I suggest you read up on static vs dynamic allocation in C
If I understand you correctly, you are trying something along the lines of:
typedef struct
{
char* val;
} A;
A alist[10];
void foo()
{
char t[10];
t = "abc";
alist[0].val = t;
}
int main()
{
foo();
}
First of all, the line
t = "abc";
is syntactically incorrect. You have to use something like:
strcpy(t, "abc");
But the most important error is that when you return from foo, alist[0].val points to an address that is not good any more. To make sure alist[0].val points to a valid address, you have to allocate memory from the heap for it and copy the contents of t to it.
void foo()
{
char t[10];
strcpy(t,"abc");
alist[0].val = malloc(strlen(t)+1);
strcpy(alist[0].val, t);
}
To do a thorough job, you'll have to make sure that you call free on that allocated memory at some point before you return from main.
You have not allocated memory for type, key, valueType and value.
Try static memory allocation :
typedef struct keyValuePairs{
char* type[n];
char* key[n];
char* valueType[n];
char* value[n];
}
Where n is a defined constant

Resources