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.
Related
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;
}
I got a binary file that contains 3 different structs which I'm suppose to read to my program. After I have read the first struct I store its size, and then I'm suppose to convert my void pointer + the first structs length to a struct ip_hdr * (which is the second struct) and then read all it's values.
But the problems is I don't understand how you move a void pointer. I have understood that the void pointers don't have the same arithmetic rules as like a int pointer.
I want to do something like this:
ptr = (struct ip_hdr *)ptr) + (ethRes));
But that doesn't work instead I get following error message:
Expression must be a pointer to a complete object type
Here is my code:
#pragma warning(disable: 4996)
#include <stdio.h>
#include <stdlib.h>
#include "framehdr.h"
#include <crtdbg.h>
int main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
FILE *fileOpen = fopen("C:\\Users\\Viktor\\source\\repos\\Laboration_3\\Laboration_3\\TCPdump", "rb");
//Pointers and variables
struct ethernet_hdr eth;
struct ethernet_hdr *ethPtr;
struct ip_hdr ip;
struct ip_hdr *ipPtr;
struct tcp_hdr tcp;
struct tcp_hdr *tcpPtr;
if (fileOpen == NULL)
{
printf("Error\n");
}
else
{
printf("Success\n");
}
char ethrr[10];
fscanf(fileOpen, "%s", ethrr);
int length = atoi(ethrr);
printf("Nr: %d\n", length);
void *ptr;
ptr = (void *)malloc(length);
fread(ptr, sizeof(eth), 1, fileOpen);
int ethRes = sizeof(((struct ethernet_hdr*)ptr)->dhost) +
sizeof(((struct ethernet_hdr*)ptr)->shost) +
sizeof(((struct ethernet_hdr*)ptr)->type);
printf("%d\n", ethRes);
printf("ptr1: %d\n", &ptr);
system("pause");
fclose(fileOpen);
return 0;
}
I now it's broken but I'm not done with it. Just need help with the pointers for now.
This should work, assuming the structure is compatible with whatever is in the file (in general saving structs "raw" to disk is a bad idea, the exact layout of a struct in memory is compiler-dependent and not stable enough to use as a file format):
const struct ip_hdr * const ip = (struct ip_hdr *) ((struct ethernet_hdr *) ptr + 1);
This adds "1" to a pointer of type ethernet_hdr, which will advance the actual pointer value by whatever size the Ethernet header structure has. The result is then cast to struct ip_hdr *.
I think this is what you wanted to do. You can do it by adding bytes to a char *, but what's the point?
You can't add directly to the void pointer, since pointer arithmetic is always in units of whatever is pointed at, and void has no size.
Here's an example of moving along an array of structures using a pointer to void.
The compiler doesn't know the type of object pointed to by a void* pointer.
So you have two choices. One is to convert it to a pointer to the 'correct' type and then add the number of elements you want to move. The other is to add the number of bytes you want to an unsigned char* (or similar).
The action happens on the lines marked [1] and [2] below.
#include <stdio.h>
typedef struct {
int payload;
double other;
} thingy;
int main(void) {
thingy athingy[2];//An array of two thingys.
void* voidptr=athingy; //a pointer to first thingy.
thingy* nextthingy=((unsigned char*)voidptr)+sizeof(thingy); //[A] next thingy points to second element of array.
thingy* altnext=((thingy*)voidptr)+1; //[B] Points to the same thing!
printf("voidptr==%p %zu\n",voidptr,sizeof(thingy));
printf("nextthingy==%p\n",nextthingy);
printf("altthingy==%p\n",altnext);
if(nextthingy==altnext){
printf("Same\n");
}else{
printf("Not same (oh dear)\n");
}
return 0;
}
Typical output:
voidptr==0x7ffd6909d660 4
nextthingy==0x7ffd6909d664
altthingy==0x7ffd6909d664
Same
The actual values may vary.
Caveat
If I understand the question, the requirement is to move through a number of different structs read together.
That may be problematic because of alignment. It's beyond the scope of this question to go into detail but C may place or require padding between members or objects of different type to ensure they are aligned on the architecture. It's very common for example for 4 byte integers to lie on memory addresses that numerically divide by 4. That simplifies hardware and improves performance.
It's not clear from the fragment provided that the objects read in will be aligned and further copying of data and shuffling may be required.
That may have been taken into account but that can't be seen from the information provided.
What may help is the often overlooked offsetof(,) macro defined in stddef.h.
That returns the offset of a member within a type (taking internal padding into consideration). For example there is in general no guarantee (above) that:
voidptr+sizeof(payload)==((unsigned char*)voidptr)+offsetof(thingy,other)
I have these structs declared :
typedef struct
{
double* weight;
char *etiquette;
double active;
}Neuron;
typedef struct
{
Neuron **grid;
Neuron *capteur;
double alpha;
int rv;
}SOM;
and then somewhere in my program I have a pointer to the second structure
SOM *net;
then I want to access the *weight variable from net. I can access it with
net->capteur->weight;
but net->grid[0][0]->weight has errors. Then I use net->grid[0][0].weight and it compiles but gives me a segmentaion fault.
What is wrong with net->capteur->weight; statement and how can I fix it?
grid and weight are pointer. Have you initialize it?
if you want to read weight value you should do:
*(net->grid[0][0].weight)
So I have one struct and I initialized a variable A with that struct data type then Ι put in some values. But now Ι need to take those values and put it into another variable B with the same struct data type. How can Ι achieve this?
struct s_Especialidade{
int id;
char nome[60];
char descricao[60];
struct s_Especialidade *proximo;
};
typedef struct s_Especialidade Especialidade;
PESPECIALIDADE p, *array;
p->nome = &array[i]->nome; //THIS LINE GIVES THE ERROR
Since it is an array of characters, you need to copy each element of the array.
strcpy(p->nome, array[i]->nome) will do it, but for extra security look at strncpy where you can set a maximum length to avoid overruns.
Try that way :
memcpy( p->nome, array[i].nome, 60 * sizeof(char) );
Or generalizing the type as well, picking the type used in the p->nome array :
memcpy( p->nome, array[i].nome, 60 * sizeof(*(p->nome)) );
This is the generalized and secure way to copy an array into another (not only for strings).
To extend the answer recommending strcpy() I'd use memcpy() and use a #defined length to make sure you always use the same value.
#define NOME_LENGTH 60
struct s_Especialidade{
int id;
char nome[NOME_LENGTH];
char descricao[60];
struct s_Especialidade *proximo;
};
typedef struct s_Especialidade Especialidade;
PESPECIALIDADE p, *array;
memcpy(p->nome, array[i]->nome, NOME_LENGTH);
Things get even more complicated trying to consider what an assignment does, but, in an example program:
struct stuff {
char buf[2];
};
int main() {
struct stuff a;
memcpy(a.buf, "aa", 2); // *Edit: "aa" is a bad example as it
// actually becomes at compilation 3 bytes long
// {'a','a','\0'} as noted in the comments
struct stuff b;
b.buf = a.buf; // *Edit: For illustrative purposes, an assignment
// between two char[2] members is not correct and
// does not compile.
}
Compilation yeilds the error error: incompatible types when assigning to type ‘char[2]’ from type ‘char *’ for the b.buf = a.buf line.
The topic of pointers and arrays has been covered elsewhere, Is an array name a pointer? among others.
*Edit: As noted in the comments, in the above code if instead of b.buf = a.buf; the struct assignemnt b = a; were done, the internal members would be copied correctly. This is because struct to struct assignment is effectively memcpy(&b, &a, sizeof(b)); (Assign one struct to another in 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.