How to modify pointer to structure inside void function - c

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;
}

Related

Passing a struct to void* param then copying it to a void*, reconstructing gives garbage value

I am really confused with passing my struct to void pointers, I'm not sure which one can be assigned directly and which one should be memcpyed, I've tried a lot of combinations but it does not seem to work. Any help would be very appreciated!
This is my C code
struct SomeStruct {
int a;
char name[10];
};
void *randoms[10];
void transferFunction(void* data, int index) {
// This function copies data to randoms[index]
// I would like to have the whole struct's data in randoms[index]
memcpy(&randoms[index], data, sizeof(struct SomeStruct));
}
struct SomeStruct *ss = malloc(sizeof(struct SomeStruct));
ss->a = 1;
strcpy(ss->name, "abc");
transferFunction(ss, 0);
My goal is to have the randoms[index] having the struct's data as another function is going to read from it, as shown below, but I am unable to retrieve the struct data correctly, it gives me some garbage value
void readFunction() {
struct *SomeStruct ss = malloc(sizeof(struct SomeStruct));
memcpy(ss, &randoms[index], sizeof(struct SomeStruct));
printf(ss->name);
}
Does anyone knows how to solve this problem? Thank you very much!!!
You can not "copy in to a void".
A void * can contain a memory address, but does not contain any information about the size of the data at that address.
Also, it can not contain any data, only an address!
In this line:
void *randoms[10];
You create an array that can hold 10 addresses.
You never initialize this array, so it will start out all zeroes (this only works for global variables in C).
You can put the address of your structure in to the array, like so:
random[0] = (void*)ss;
However, this does not transfer any data, so if you free the original structure (ss) your data is gone, and the address in random[0] is illegal.
If you want to transfer data you need to create array of struct SomeStruct or you need to allocate another SomeStruct, store its address in random[0] then memcpy to that address.
void transferFunction(void* data, int size, int index)
{
randoms[index] = malloc(size);
if (randoms[index] != NULL) {
memcpy(randoms[index], data, size);
}
}
Your code has some problems:
struct *SomeStruct ss = ... should be struct SomeStruct *ss =.
You are not cheking the return value of malloc() (which may fail).
You are not freeing ss allocated with malloc(). You should call free() on ss.
My goal is to have the randoms[index] having the struct's data
Lev M.'s answer already answers this part.
as another function is going to read from it
Simply assign your void pointer to a SomeStruct pointer:
void readFunction(int index)
{
if (index >= 10) // Index out of range
return;
struct SomeStruct *ss = randoms[index];
printf("%s\n", ss->name);
}

load data to struct and display, c

I am new to use C programming and trying to fill a structure and print the actual data stored in my struct. I'm stuck with segfault. see my sample code:
main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stddef.h>
struct full_data
{
char *first_name;
char *last_name;
int *id_code;
};
struct owner
{
int *owner_code;
struct full_data tdata;
};
void display_my_output(struct owner *mydata)
{
printf("My data should be: \nfirst_name: %s\nlast_name: %s\nid_code: %d\nowner_id: %d\n",mydata->tdata.first_name ,mydata->tdata.last_name,mydata->tdata.id_code,mydata->owner_code);
}
int main()
{
int i;
struct owner *own;
for(i=0 ; i<4 ; i++)
{
if(i==0)
{
own->tdata.first_name = "PAUL";
}
if(i==1)
{
own->tdata.last_name = "ROOT";
}
if(i==2)
{
own->tdata.id_code =30001;
}
if(i==3)
{
own->owner_code = 2*i;
}
}
display_my_output(own);
return 0;
}
Am expecting my out put as:
My data should be:
first_name: PAUL
last_name: ROOT
id_code: 30001
owner_id: 6
Do i miss something in my code?
Yes, you are missing the fact that you declare and use a pointer to a struct owner, which means that you must initialize it.
So you could do
struct owner *own = calloc(1, sizeof(struct owner));
..
free(own);
but if you don't need to allocate it on heap then you could just allocate it on stack:
struct owner own;
own.tdata.first_name = ...;
Allocating it on the stack wouldn't prevent you from getting the address and pass it to display_my_output function. You just need to call it through display_my_output(&own);.
You need to initialize struct owner *own; using malloc() like this:
own = (struct owner*) malloc(sizeof(struct owner);
and don't forget to free memory at the end:
free(own);
Also, in both your structs, you are making a pointer to an integer rather than integer. I don't think you need an int*.
struct owner *own; declares a pointer to struct owner. Yes, now the compiler knows that the object own points to is a struct owner, but which struct owner is it pointing to? The compiler didn't know, because you didn't tell it.
In fact, an uninitialised pointer may point to an invalid/unavailable memory address, or contain a "trap representation". The result of either of them is undefined behaviour, which causes segfault in your case.
To fix this, write
struct owner *own = malloc(sizeof(struct owner));
The call to malloc() allocates a block of memory to hold a struct owner to own; thus it'll be pointing to valid memory.
Also, don't forget to add free(own) before main() returns, or you will get a memory leak.

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.

Accessing members in a pointer to a pointer of a struct

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.

Struct to bidimensional struct pointer assignment in C

I want to get work this code and I googled and asked in efnet and freenode but I didn't find the answer.
What I want is to assign a struct woot to an another bidimensional struct woot *, and I need malloc to do that.
Then, how can I use malloc there and how to assign the struct? Thanks.
#include <stdio.h>
struct omg {
int foo;
};
struct woot {
struct omg *localfoo;
int foo;
};
int a = sizeof(struct woot);
int main(void){
struct woot *what[10][10] = (struct woot *) malloc(100*a);
struct omg hahaha[100];
hahaha[1].foo = 15;
what[1][6].localfoo = &hahaha[1];
}
struct woot *what[10][10] = (struct woot *) malloc(100*a);
I'm curious, does this code even compile? (edit: no, it doesn't.) In any case:
You don't really need malloc() here, declaring struct woot *what[10][10]; should be enough.
Typecasting the returned void* pointer when calling malloc() is unneeded in C (and considered as bad form).
(Not really an answer, I know... I would post it as a simple comment but I don't have enough points yet.)
edit: Oops, others have pointed out the same while I was writing this post.
new edit: Here is a better version of your code, with some mistakes corrected:
#include <stdio.h>
#include <stdlib.h> // needed for malloc()
struct omg {
int foo;
};
struct woot {
struct omg *localfoo;
int foo;
};
int main(void){
const int a = sizeof(struct woot); /* there is no reason "a" should be global...
actually, "a" is not needed at all, and, even if it
were needed, it should be declared as "const" :) */
struct woot *what[10][10];
struct omg hahaha[100];
hahaha[1].foo = 15;
what[1][6]->localfoo = &hahaha[1];
what[7][2] = malloc(a); // I would write "malloc(sizeof(struct woot))"
return 0; // main() should return an int, as declared!
}
You're trying to initialize an array with a scalar value (the pointer returned by malloc). If you really want a 10 by 10 matrix of pointers to structs (and not a 10 by 10 matrix of structs), you don't need malloc:
//Statically allocated 10x10 matrix of pointers, no need for malloc.
struct woot *what[10][10];
To assign a pointer to a cell in that matrix:
struct woot oneSpecificWoot;
what[1][2] = &oneSpecificWoot;
If this is really, really what you want, you could then create a bunch of woots dynamically an populate it. Something like this:
int i, j;
for(i=0; i<10; i++) {
for(j=0; j<10; j++) {
what[i][j] = malloc(sizeof(struct woot));
//Of course, you should always test the return value of malloc to make sure
// it's not NULL.
}
}
But if you're going to do that, you might as well just statically allocate the woots themselves:
//A 10x10 matrix of woots, no malloc required.
struct woot what[10][10];
The first case (a 2-D array of pointers) would be more likely if the woots are being created somewhere else, and you just want references to them in a grid lay out, or possibly if you don't know the dimensions of the grid at compile time. But in your code, you're using malloc to create a fixed number of them, so you might as well just have the compiler allocate them statically.

Resources