I am trying to access my struct points. The structs memory are dynamically located. I am getting a segmentation fault that I can't figure out. My struct definitions from my .h file are as follows:
struct point{
double x;
double y;
};
struct figure{
char name[128];
int draw;
struct point *points;
};
extern struct figure *figures;
In my .c file I have:
struct figure *figures;
//initializing 10 figures
figures = malloc(10 * sizeof(struct figure));
//left the obvious NULL checking out for brevity
//I'm fairly sure this portion works for initializing 10 points for each figure
int i;
for(i = 0;i<10;i++){
figures[i].points = malloc(10 * sizeof(struct point));
//left out NULL checking again
}
Unless a problem was detected before this point this is where I am having trouble, actually storing values into points.
NOTE: index could be any int >= 0, just using a general term for simplicity
figures[index].points[index]->x = 10;
figures[index].points[index]->y = 15;
Any help with his problem would be fantastic. Thanks in advance.
figures[index].points is an array of structures, which means that indexing it (i.e. figures[index].points[index]) gives you a structure. The last two lines should be:
figures[index].points[index].x = 10;
figures[index].points[index].y = 15;
I'm surprised the compiler wouldn't catch this.
Apart from the fact that you are accessing the inner structure incorrectly,I don't see any problem in this code.
Online Demo of your code sample that works.
#include<string.h>
#include<stdio.h>
struct point{
double x;
double y;
};
struct figure{
char name[128];
int draw;
struct point *points;
};
int main()
{
struct figure *figures;
figures = malloc(10 * sizeof(struct figure));
int i = 0;
for(i = 0;i<10;i++)
{
figures[i].points = malloc(10 * sizeof(struct point));
figures[i].draw = i;
}
i = 0;
for(i = 0;i<10;i++)
{
printf("\nfigures[%d].draw = [%d]",i,figures[i].draw);
int j;
for(j = 0;j<10;j++)
{
figures[i].points[j].x = i;
figures[i].points[j].y = j;
printf("\nfigures[%d].points[%d].x = [%f]",i,j,figures[i].points[j].x);
printf("\nfigures[%d].points[%d].y = [%f]",i,j,figures[i].points[j].y);
}
}
return 0;
}
Output:
figures[0].draw = [0]
figures[0].points[0].x = [0.000000]
figures[0].points[0].y = [0.000000]
figures[0].points[1].x = [0.000000]
figures[0].points[1].y = [1.000000]
figures[0].points[2].x = [0.000000]
...so on
Related
I have this two structures:
typedef struct {
unsigned int rows;
unsigned int cols;
Cell ***cells;
} Board;
typedef struct {
unsigned int info;
unsigned char state;
unsigned int mines;
} Cell;
initialized the board structure:
board = (Board*) malloc(sizeof(Board));
board->rows = 2;
board->cols = 2;
board->cells = NULL;
after that I call this function:
int initCells(Board **board) {
Cell **cells = (Cell**) malloc((*board)->rows * sizeof(Cell*));
for (int i = 0; i < (*board)->rows; i++) {
cells[i] = (Cell*) malloc((*board)->cols * sizeof(Cell));
}
(*board)->cells = &cells;
(*board)->cells[0][0]->info = 7;
(*board)->cells[0][1]->info = 7;
(*board)->cells[1][0]->info = 7; // segmentation fault
return 0;
}
Why do I get on the third segmentation fault and what would be the correct way to allocate memory to the triple pointer?
(*board)->cells = &cells;
This sets the board cells pointer to point to a local variable from the function. When the function returns that pointer is no longer valid.
It seems like yo have one pointer level too many. There is no reason I can see for the third level.
Also the second level on the board parameter just complicates things, but is is totally superfluous.
I was doing my Huffman homework and I got stumble on a tiny thing that I cant understand why it happens.
So I created a structure that has an int array a char and an int that holds the size of the array.
struct kodlar{
char karakter;
int* code;
int codesize;
};
typedef struct kodlar kodlar;
kodlar* yenikod(char karakter, int* code,int codesize){
kodlar* yenikod = (kodlar*)malloc(sizeof(kodlar));
if(yenikod){
yenikod->karakter = karakter;
yenikod->code = code;
yenikod->codesize = codesize;
}
return yenikod;
}
Then inside of my main, I created an array that holds these structures:
kodlar* K[taille];
taille is the number of char that it is going to store.
In order to put the characters and codes correspondence, I created the function
printCodes(HuffTree,arr,top,&p,K);
and it works like this:
void printCodes(node* root, int arr[], int top,int* i,kodlar** K)
{
if (root->left) {
arr[top] = 0;
printCodes(root->left, arr, top + 1,i,K);
//printf("%c\n",'l');
}
if (root->right) {
arr[top] = 1;
printCodes(root->right, arr, top + 1,i,K);
//printf("%c\n",'r');
}
if (isLeaf(root)) {
printArr(arr,top);
K[*i]=yenikod((root->lettre),arr,top);
*i = *i + 1;
//printArr(K[*i]->code,K[*i]->codesize);
//printf("%i en son if te i \n",*i );
}
}
But it seems like I cant store arrays inside of my array of kodlar structure. if I commented out the parties //printArr(K[*i]->code,K[*i]->codesize); it gives me a segmentation fault and if I try to print like this:
for (int i = 0; i < taille; ++i){
printf("%c :", K[i]->karakter);
printf(" ");
printArr(K[i]->code,K[i]->codesize);
printf("\n");
}
it gives me codes but only with 1's. I got stuck on this it has been 2 days I would appreciate it if somebody can help me.
struct kodlar{
char karakter;
int codesize;
int code[50];
};
typedef struct kodlar kodlar;
kodlar* yenikod(char karakter, int* code,int codesize){
kodlar* yenikod = (kodlar*)malloc(sizeof(kodlar));
if(yenikod){
yenikod->karakter = karakter;
yenikod->codesize = codesize;
for (int i = 0; i < codesize; ++i)
{
yenikod->code[i] = code[i];
}
}
return yenikod;
}
So thanks to #wcochran I understood that the problem was in my struct but memcpy did not work on my code and I was already giving an array that has been already allocated before entering to yenikod. And I gave a size to my code array in the kodlar struct and my problem was solved.
If i had an array such as int numbers[5] i could assign values to it with numbers[0] = 1 or numbers[3] = 4. Then if i had a struct such as
struct structName
{
int number0;
int number1;
int number2;
};
is there any way to do something like the following (note this is not working code)
int main(void)
{
struct structName name; //how could i declare this to do the following
for(int i = 0; i < 2; i++)
{
name[i] = i; //maybe name.[i]
}
}
so is there a way to write name[ variable ] = someNumber to assign someNumber to say number0 (if variable was 0) or number2 (if variable was 2). ive been looking for days and cant find anything that does this. (maybe i just don't know what to look for)
is there any way to do something like the following
No, there's no way to access the fields of the structure by index. You use the names of the fields instead:
struct structName name;
name.number0 = someNumber;
name.number1 = someOtherNumber;
If you want to access the values by index, use an array instead, even if it's embedded in the structure:
struct structName
{
int numbers[3];
// other fields here
};
Then you can say:
struct structName name;
for (int i = 0; i <= 2, i++) {
name.numbers[i] = i;
}
You could write a function which uses a switch statement that allows you to access fields by index. Something like:
#include<stdio.h>
struct structName{
int number0;
int number1;
int number2;
};
void assign(struct structName * name, int i, int j){
switch(i){
case 0:
name->number0 = j;
break;
case 1:
name->number1 = j;
break;
case 2:
name->number2 = j;
break;
}
}
int main(void){
int i;
struct structName name;
for(i = 0; i <= 2; i++){
assign(&name,i,i);
}
//test:
printf("%d\n",name.number0);
printf("%d\n",name.number1);
printf("%d\n",name.number2);
return 0;
}
(which prints 0,1,2 as expected).
Needless to say, there isn't much point in doing this (as opposed to just having a field which is an array) unless the struct in question is already defined as part of an API or already part of a code base which isn't easily refactored.
Yes, with some weird and inadvisable memory manipulation. You're much better off using an array.
struct structName
{
int numbers[3];
};
int main(void)
{
struct structName name;
for(int i = 0; i <= 2; i++)
{
name.numbers[i] = i;
}
}
Also note that you had some syntax errors in your for loop and an off-by-one error.
Macros with arguments should work
#define name(x) x
So name(1) would become 1. name(2) would become 2 and so on.
In C, there is no spoon.
struct structName name;
int *idx = &name; // First we need a memory address to the struct
for (int i = 0; i < sizeof(name) / sizeof(*idx); ++i) {
// idx[i] == name.numberX
idx[i] = i;
}
Now, if you check the values of name.number0, name.number1, name.number2 you will see they contain the correct values.
This is not a very good way of doing things with structs, but I felt compelled to answer after the top response claims it is impossible.
I have a function
struct Analysis reduce (int n, void* results)
Where n is the number of files to be analyzed, and I'm passing an array of Analysis structs to results.
The Analysis struct is defined as follows:
struct Analysis {
int ascii[128]; //frequency of ascii characters in the file
int lineLength; //longest line in the file
int lineNum; //line number of longest line
char* filename;
}
I've cast the void * as such,
struct Analysis resArray[n];
struct Analysis* ptr = results;
resArray[0] = ptr[0];
but I can't figure out how to iterate through the resArray properly. I've tried
for (i = 0; i < n; i++){
printf("lineLength: %d\n", resArray[i].lineLength);
}
with n = 3, and I'm getting garbage values. resArray[0] is correct, but resArray[1] is an insanely high number and resArray[2] is just 0. Why wouldn't resArray[1] or resArray[2] give the correct values? If I was incrementing the address incorrectly then it would make sense but I'm just accessing the array at a certain index. Pretty lost here!
resArray[0] is correct because there is "something":
resArray[0] = ptr[0];
Other elements are garbage because you didn't set there any values. If you want to copy entire array you need to change copying method to:
for (i = 0; i < n; i++)
{
resArray[i] = ptr[i];
}
You can't assign a pointer to an array directly because they are different typessince array[n] is type struct analysis(*)[n] and ptr is type struct analysis(*). Check here for more info.
Hopefully this code will help you.
#include <stdio.h>
#define d 3
struct Analysis {
int ascii[128];
int lineLength;
int lineNum;
char *filename;
};
struct Analysis Analyses[d];
struct Analysis reduce(int n, void *results) {
struct Analysis resArray[n];
struct Analysis *ptr = results;
for (int i = 0; i < n; i++) {
resArray[i] = ptr[i];
}
for (int i = 0; i < n; i++) {
printf("lineLength: %d\n", ptr[i].lineLength);
}
return *ptr;
}
int main(void) {
struct Analysis a = {{5}, 2, 2, "George"};
struct Analysis b = {{6}, 3, 3, "Peter"};
struct Analysis c = {{7}, 4, 4, "Jane"};
Analyses[0] = a;
Analyses[1] = b;
Analyses[2] = c;
reduce(d, &Analyses);
return 0;
}
You can try it online.
I don't get why MPI_Reduce() does a segmentation fault as soon as I use a custom MPI datatype which contains dynamically allocated arrays. Does anyone know ? The following code crashes with 2 processors, inside the MPI_Reduce().
However If I remove the member double *d int MyType and changes the operator and MPI type routines accordingly, the reduction is done without any problem.
Is there a problem using dynamically allocated arrays or is there something fundamentally wrong with what I do :
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
typedef struct mytype_s
{
int c[2];
double a;
double b;
double *d;
} MyType;
void CreateMyTypeMPI(MyType *mt, MPI_Datatype *MyTypeMPI)
{
int block_lengths[4]; // # of elt. in each block
MPI_Aint displacements[4]; // displac.
MPI_Datatype typelist[4]; // list of types
MPI_Aint start_address, address; // use for calculating displac.
MPI_Datatype myType;
block_lengths[0] = 2;
block_lengths[1] = 1;
block_lengths[2] = 1;
block_lengths[3] = 10;
typelist[0] = MPI_INT;
typelist[1] = MPI_DOUBLE;
typelist[2] = MPI_DOUBLE;
typelist[3] = MPI_DOUBLE;
displacements[0] = 0;
MPI_Address(&mt->c, &start_address);
MPI_Address(&mt->a, &address);
displacements[1] = address - start_address;
MPI_Address(&mt->b,&address);
displacements[2] = address-start_address;
MPI_Address(&mt->d, &address);
displacements[3] = address-start_address;
MPI_Type_struct(4,block_lengths, displacements,typelist,MyTypeMPI);
MPI_Type_commit(MyTypeMPI);
}
void MyTypeOp(MyType *in, MyType *out, int *len, MPI_Datatype *typeptr)
{
int i;
int j;
for (i=0; i < *len; i++)
{
out[i].a += in[i].a;
out[i].b += in[i].b;
out[i].c[0] += in[i].c[0];
out[i].c[1] += in[i].c[1];
for (j=0; j<10; j++)
{
out[i].d[j] += in[i].d[j];
}
}
}
int main(int argc, char **argv)
{
MyType mt;
MyType mt2;
MPI_Datatype MyTypeMPI;
MPI_Op MyOp;
int rank;
int i;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
mt.a = 2;
mt.b = 4;
mt.c[0] = 6;
mt.c[1] = 8;
mt.d = calloc(10,sizeof *mt.d);
for (i=0; i<10; i++) mt.d[i] = 2.1;
mt2.a = 0;
mt2.b = 0;
mt2.c[0] = mt2.c[1] = 0;
mt2.d = calloc(10,sizeof *mt2.d);
CreateMyTypeMPI(&mt, &MyTypeMPI);
MPI_Op_create((MPI_User_function *) MyTypeOp,1,&MyOp);
if(rank==0) printf("type and operator are created now\n");
MPI_Reduce(&mt,&mt2,1,MyTypeMPI,MyOp,0,MPI_COMM_WORLD);
if(rank==0)
{
for (i=0; i<10; i++) printf("%f ",mt2.d[i]);
printf("\n");
}
free(mt.d);
free(mt2.d);
MPI_Finalize();
return 0;
}
Let's look at your struct:
typedef struct mytype_s
{
int c[2];
double a;
double b;
double *d;
} MyType;
...
MyType mt;
mt.d = calloc(10,sizeof *mt.d);
And your description of this struct as an MPI type:
displacements[0] = 0;
MPI_Address(&mt->c, &start_address);
MPI_Address(&mt->a, &address);
displacements[1] = address - start_address;
MPI_Address(&mt->b,&address);
displacements[2] = address-start_address;
MPI_Address(&mt->d, &address);
displacements[3] = address-start_address;
MPI_Type_struct(4,block_lengths, displacements,typelist,MyTypeMPI);
The problem is, this MPI struct is only ever going to apply to the one instance of the structure you've used in the definition here. You have no control at all of where calloc() decides to grab memory from; it could be anywhere in virtual memory. The next one of these type you create and instantiate, the displacement for your d array will be completely different; and even using the same struct, if you change the size of the array with realloc() of the current mt, it could end up having a different displacement.
So when you send, receive, reduce, or anything else with one of these types, the MPI library will dutifully go to a probably meaningless displacement, and try to read or write from there, and that'll likely cause a segfault.
Note that this isn't an MPI thing; in using any low-level communications library, or for that matter trying to write out/read in from disk, you'd have the same problem.
Your options include manually "marshalling" the array into a message, either with the other fields or without; or adding some predictability to where d is located such as by defining it to be an array of some defined maximum size.