I've those two structs :
typedef struct
{
char* name;
int flightCount;
Flight** flightArr;
LIST dateList;
int flightsSorted;
}Airline;
typedef struct
{
Airport* airportsArr;
int airportsCount;
}AirportManager;
and I need to write a general printer for both arrays (one is struct array and the other is pointer array).
I know that general printer should look like that:
void generalArrayFunction(const void* pArr, const int size, int sizeOfElement, void(*printer)(const void*))
{
for(int i=0;i<size;i++)
printer((char*)pArr + i * sizeOfElement);
}
and it's work great with the regular array which I print with the following line:
generalArrayFunction(manager.airportsArr,manager.airportsCount,sizeof(manager.airportsArr[0]),printAirport);
but with the pointer array I can't use the same logic and I dont know what should I do.the following line prints one struct but the second one messed up.
generalArrayFunction(*pComp->flightArr, pComp->flightCount, sizeof(pComp->flightArr[0]), printFlight);
any suggestions ?
If i got your intention right, In this code:
generalArrayFunction(*pComp->flightArr, pComp->flightCount, sizeof(pComp->flightArr[0]), printFlight);
sizeOfElement will be the size of a pointer because it's an array of pointers, you need to make another dereference to reach the struct and get the size, that's why the first struct is printing ok and the subsequent are not.
Try this:
generalArrayFunction(*pComp->flightArr, pComp->flightCount, sizeof((*pComp->flightArr)[0]), printFlight)
Related
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.
If I have two structs:
typedef struct{
unsigned int time;
double rate;
}quote;
typedef struct{
unsigned int freeSlots;
unsigned int end;
unsigned int start;
unsigned int currSize;
unsigned int maxSize;
unsigned int startAt;
//unsigned int currIndex;
quote quoteBuffer[1];
}cbuf;
And I wanted to make a function that would modify the size of the quoteBuffer array inside cbuf, how exactly would I go about doing that? I have tried a few approaches but none have worked so far. I keep returning to the same format of:
quote *newQuoteBuffer = malloc(sizeof(quote) * newSize);
And if I already have an existing cbuf somewhere (for example, we will call it "a" where a is the pointer to the cbuf):
a->quoteBuffer = newQuoteBuffer;
But obviously this doesn't work. Any hints?
This:
quote quoteBuffer[1];
should be:
quote *quoteBuffer;
Then the assignment will work.
Dereferencing quote looks like this:
a->quoteBuffer->time;
If you later have multiple elements of quote allocated with malloc() you can access them like this:
a->quoteBuffer[i].time;
If you are not sure of how many elements will go into the quoteBuffer, maintain a linked list of the same. For that
quote *quoteBuffer;
And keep adding or removing the elements to/from the buffer as required.
I think you're missing the point of why someone would have the last element of a struct as a single element array. This is a trick that's used in old C code as a way to make the struct size variable length.
You can write code such as this:
Bitmapset *p = malloc(offsetof(Bitmapset, quoteBuffer) + n * sizeof(quote));
Then you write code like this:
p->quoteBuffer[0]
up to:
p->quoteBuffer[n-1]
You do not want to assign a pointer directly to quoteBuffer, as you guessed.
So, why would you want to declare quoteBuffer as:
quote quoteBuffer[1];
instead of
quote* quoteBuffer;
?
It's because you do not wanna to have a separate allocation for quoteBuffer. A single allocation can be used for the entire cbuf, including the inline quote array.
There are two approaches. One is to use a pointer in cbuf, as others have mentioned, by changing
quote quoteBuffer[1];
to
quote* quoteBuffer;
The other is to resize the cbuf:
#include <stddef.h> // for offsetof
struct cbuf* realloc_cbuf(struct cbuf* cbufp, size_t nquotes)
{
struct cbuf* new_cbufp = realloc(cbufp, offsetof(struct cbuf, quoteBuffer) + nquotes * sizeof *cbufp->quoteBuffer);
if (!new_cbufp)
{
// handle out of memory here. cbufp is still intact so free it if you don't need it.
}
return new_cbufp;
}
void elsewhere(void)
{
struct cbuf* acbuf = NULL;
acbuf = realloc_cbuf(1);
acbuf = realloc_cbuf(10);
// etc.
}
I have this array filled up with characters in my maze.c file:
char normalMazeArray[6][12]; dynamically filled as mazeArray[row][column]
Now I want to pass what the array to the mazeArray that is located in my struct (maze.h)
my struct is called:
typedef struct {
char mazeArray;
} maze_t;
I have tried copying it as follows:
maze_t* maze;
char normalMazeArray[6][12]; // filled with info
typedef struct {
char mazeArray;
} maze_t;
maze->mazeArray = normalMazeArray;
however it is not working,
anyone who could help me?
The thing what you're trying to do is not exactly possible. There are two slightly different solutions you can use, though.
normalMazeArray is of type char [6][12] - it's an array. You can either copy its contents to the same type of array using memcpy():
typedef struct {
char mazeArray[6][12];
} maze_t;
memcpy(maze->mazeArray, normalMazeArray, sizeof(normalMazeArray));
or if your normalMazeArray persists throughout the lifetime of the program, you can assign a pointer to it in the structure:
typedef struct {
char (*mazeArray)[12];
} maze_t;
maze->mazeArray = normalMazeArray;
Wait, how??
First of all, maze is a pointer, so you can't have maze.mazeArray. Second of all, maze->mazeArray is of type char, while mazeArray is of type char**. No can do.
You should write a function which allocates char** array, and then strdups strings from mazeArray. Or, if you want ownership transfer, and not just copy, you could go like this:
typedef struct {
char** mazeArray;
} maze_t;
maze_t maze;
maze.mazeArray = mazeArray;
I have got struct and function , and i want to assign one array poiner to pointer in my struct:
struct
{
int array[3][2]
}some_struct;
void example(some_struct* st, int array[3][2])
{
//st->array=array
//st->array[0]=array[0],st->array[1]=array[1],st->array[2]=array[2]
// how to do that ??
}
Unfortunately arrays by themselves cannot be assigned.
Since both arrays have the same dimensions and sizes (do they?) the easiest is to use memcpy:
memcpy(st->array, array, sizeof st->array);
First of all, it would be much simpler if you used one-dimensional tables. Here's the example. Note the difference between holding a pointer and a fixed-size table!
typedef struct
{
int* array;
} some_struct;
void example (some_struct* st, int* array)
{
st->array = array;
}
If you still want to use 2-dimensional ones, you really need to assign every table of the 2nd level, as they don't have to be linear in memory.
EDIT: If the 2-dimensional arrays are indeed always linear in memory in C, the above statement should work if you give it 2-dimensional array as a parameter to example function.
If you just wish to copy the values as I see it, I would do it like that:
struct
{
int array[3][2]
}some_struct;
void example(some_struct* st, int *array, int dim)
{
int i;
for(i = 0; i<dim; i++)
st->array[i]=array[i];
}
//Use:
some_struct try_st;
array[3][2] orig_st;
//put your data in the array
example(try_st, orig_st, 3*2);
If array is the first member in your struct-declaration you can simple copy it like:
struct
{
int array[3][2]
}some_struct;
void example(some_struct* st, int array[3][2])
{
*st = *(some_struct*)array;
}
All other struct-members are destroyed here, it make only sense if your struct contains only the array member.
I'm having trouble passing an array of structs to a function in C.
I've created the struct like this in main:
int main()
{
struct Items
{
char code[10];
char description[30];
int stock;
};
struct Items MyItems[10];
}
I then access it like: MyItems[0].stock = 10; etc.
I want to pass it to a function like so:
ReadFile(MyItems);
The function should read the array, and be able to edit it. Then I should be able to access the same array from other functions.
I've tried heaps of declarations but none of them work.
e.g.
void ReadFile(struct Items[10])
I've had a look around for other questions, but the thing is they're all done different, with typedefs and asterisks. My teacher hasn't taught us pointers yet, so I'd like to do it with what I know.
Any ideas? :S
EDIT: Salvatore's answer is working after I fixed my prototype to:
void ReadFile(struct Items[10]);
struct Items
{
char code[10];
char description[30];
int stock;
};
void ReadFile(struct Items items[10])
{
...
}
void xxx()
{
struct Items MyItems[10];
ReadFile(MyItems);
}
This in my compiler works well.
What compiler are you using? What error you got?
Remember to declare your struct before your functions or it will never work.
Define struct Items outside of main. When passing an array to a function in C, you should also pass in the length of the array, since there's no way of the function knowing how many elements are in that array (unless it's guaranteed to be a fixed value).
As Salvatore mentioned, you also have to declare (not necessarily define) any structs, functions, etc. before you can use them. You'd usually have your structs and function prototypes in a header file in a larger project.
The below is a working modification of your example:
#include <stdio.h>
struct Items
{
char code[10];
char description[30];
int stock;
};
void ReadFile(struct Items items[], size_t len)
{
/* Do the reading... eg. */
items[0].stock = 10;
}
int main(void)
{
struct Items MyItems[10];
ReadFile(MyItems, sizeof(MyItems) / sizeof(*MyItems));
return 0;
}
The function won't know that the type struct Items exists if you declare it only locally inside the main function body scope. So you should define the struct outside:
struct Item { /* ... */ };
void ReadFile(struct Items[]); /* or "struct Item *", same difference */
int main(void)
{
struct Item my_items[10];
ReadFile(my_items);
}
This is dangerous of course since ReadFile has no idea how big the array is (arrays are always passed by decay-to-pointer). So you would typically add this information:
void ReadFile(struct Items * arr, size_t len);
ReadFile(my_items, 10);
Instead of your declaration, declare in that way:
typedef struct {
char code[10];
char description[30];
int stock;
}Items;
and the function like that:
void ReadFile(Items *items);
With typedef you define a new type, so you don't need to use word "struct" each time.
You pretty much have to use pointers for this. You function would look like this:
void ReadFile(Items * myItems, int numberOfItems) {
}
You need to use pointer to array, after that its easy to access its members
void ReadFile(Items * items);
should work.
Well, when you pass a structure like you did, it actually creates a local copy of it in the function. So it will have no effect on your original structure, no matter how you modify it in ReadFile.
I am not sure about a different approach and this might not answer your question, but I recommend you try pointers. You'll definitely be using them quite a lot in C/C++. And they can be really powerful once you master them
Have you tried to declare you function like this:
void ReadFile(struct Items[])
Might be helpful:
http://www.daniweb.com/software-development/cpp/threads/105699
Why dont you use pass the pointer to the array to the methods that need it?
If you want the same struct array then you should use pointer to the array and not pass as array as that will create a copy.
void ReadFile(struct Items * items);
and where you call it
struct Items myItems[10];
ReadFile(myItems);
Need to be careful with pointers...