I am working on assignment. I started with the struct:
struct figures_struct
{
char figure_name[130];
double figure_coordinates[1000000];
};
When I read name of the figure from the file, I stored it into the struct as follows:
strcpy(figures[i].figure_name,f_name);
Now I have to modify my code and need to use dynamic memory. I did:
struct figures_struct
{
char figure_name[130];
double figure_coordinates[100000];
};
struct figures_struct *figures = malloc(size * sizeof(struct figures_struct));
Now, how do I store figure name into my struct? figures[i].figure_name does not seem to be working.
strcpy(figures[i].figure_name, f_name);
That will still work with pointers(as pointers and arrays are almost interchangeable in C)
It will work as soon as "i" is less than "size".
Related
I'm writing an extension for postgres which includes creating a new variable-length base type, however I'm having some difficulty understanding the semantics of SET_VARSIZE.
Take the following example code, this doesn't precisely reflect my use case but it illustrates the point.
typedef struct another_struct
{
char *a;
char *b;
} another_struct;
typedef struct test_struct
{
char vl_len_[4];
another_struct *data;
} test_struct;
1) When allocating memory for new instances of test_struct, presumably I can simply do the following, and it would take into account the size of the variable-length member vl_len_?
test_struct *t = palloc0(sizeof(struct test_struct));
2) Because both members of another_struct have variable lengths, I assume I also need to keep track of how much memory was allocated for both fields in order to pass the right length to SET_VARSIZE?
3) Do I also need to take into account the size of the another_struct pointer when calling SET_VARSIZE?
I'm thinking the final call to SET_VARSIZE would look something like this
SET_VARSIZE(t, sizeof(struct test_struct) + sizeof(struct another_struct) + a_and_b_length);
Is this close to being correct? Apologies for any mistakes, I'm rather new to programming in C.
Thanks
You can't do it that way with just a regular pointer. All the memory has to be together after the size member.
typedef struct another_struct
{
char a[FLEXIBLE_ARRAY_MEMBER];
char b[FLEXIBLE_ARRAY_MEMBER];
} another_struct;
typedef struct test_struct
{
char vl_len_[4];
another_struct data;
} test_struct;
and you have to know the actual size of your data now.
test_struct *t = palloc0(VARHDRSZ + size_of_a + size_of_b);
SET_VARSIZE(t, VARHDRSZ + size_of_a + size_of_b );
memcpy(t->data.a, src_a, size_of_a);
memcpy(t->data.b, src_b, size_of_b);
The example in the docs only has one field, so I'm only presuming this works this way.
There might be other issues with the indirection.
source: https://www.postgresql.org/docs/current/xfunc-c.html
(Homework question)
I'm just learning C, and I'm making a program that reads data from a file, creates routers of that data, and puts pointers to the routers in an array of size 255, but I keep getting the title error on the line where I'm trying to add them to the array
#define ARRAY_SIZE 255
struct router routers[ARRAY_SIZE] = {0};
int main(int argc, char *argv[]){
unsigned char id;
char name[32];
struct router *new_router;
if(argc == 2){
//reads file with fread
//setting id and name which prints out as expected
new_router = make_router(id, name); //initialising method that returns a router pointer
routers[new_router->id] = new_router;
//error occurs here, at [new_router->id]. Have also tried just using id
}
}
I've searched a lot of threads with the same error message, but they're all either someone who didn't declare an array, or were suggested to try it with unsigned char as index number, which is what I'm already using. Would love some insight into this.
struct router{
unsigned char id;
char name[32];
}
struct router* make_router(unsigned char id, char* name){
struct router *r = malloc(sizeof(struct router));
r->id = id;
r->name = name;
return r;
}
Assuming make_router allocates a struct dynamically, then
routers[new_router->id] = *new_router; // note *
solves the compiler error.
However, you cannot copy structs like this if they have pointer members. You say that "Router is just a basic struct with an unsigned char for id, and a char* for name" so this is the case. But with an assignment like this, you won't get a hard copy of the pointed-at data.
Pointers are not data. They do not contain data. They point at data allocated elsewhere.
So probably what you are actually looking for is an array of pointers, as suggested in another answer. If so, you have to re-write this program.
This:
struct router routers[ARRAY_SIZE] = {0};
means routers is an array of ARRAY_SIZE structures. Not pointers to structures, which is what this:
routers[new_router->id] = new_router;
is trying to assign into one of the elements.
If make_router() is dynamically allocating the memory, the fix is probably to change the array declaration into an array of pointers:
struct router * routers[ARRAY_SIZE];
^
|
way
important
EDIT: Of course, I assumed that there was an actual declaration of struct router somewhere that you just omitted. Might be a good idea to include it, just for completeness' sake.
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.
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 a file in a known format and I want to convert it to a new format, eg.:
struct foo {
char bar[256];
};
struct old_format {
char name[128];
struct foo data[16];
};
struct new_format {
int nr;
char name[128];
struct foo data[16];
};
static struct old_format old[10];
static struct new_format new[10];
Problem: after filling 'old' with the data I don't know how to copy its content to 'new'. If I do
new[0].name = old[0].name;
new[0].data = old[0].data;
I get a compile error about assigning char * to char[128] (struct foo * to struct foo[16], respectively).
I tried a solution I found via Google for the string part:
strcpy (new[0].name, old[0].name);
new[0].data = old[0].data;
but I have no idea how to handle the struct. Seems I lack basic understanding of how to handle arrays but I don't want to learn C - I just need to complete this task.
If you don't want to learn C, you should be able to read the old file format in any language with a half-decent IO library.
To complete what you're trying to do in C, you could use memcpy.
So instead of:
new[0].data = old[0].data;
Use
memcpy(new[0].data, old[0].data, sizeof(foo) * 16);
You can also wrap the C arrays in a struct. Then copying elements will copy the array automatically.
typedef struct {
char name[100];
} name_array_t;
struct {
name_array_t name_struct;
...
} x;
struct {
name_array_t name_struct;
... other members ...
} y;
x.name_struct = y.name_struct;
(too obvious solution may be)
As we are dealing with the array, we can not do this kind of operation
new.name = old.name;
so i suppose you have to write a function
void Function (char *name , struct new_format *new );
where you need to assign charecter one by one.
Obviously you will Call like this : Function (old.name , &new)