segmentation fault while trying to write to element of struct array - c

#include <stdio.h>
#include <stdlib.h>
struct item{
int man;
};
int writeto(struct item **itens, int n){
*itens = malloc(sizeof(struct item)*n);
for (int i = 0; i < n; i++){
itens[i]->man = i*2;
}
}
int main(){
struct item* itens;
writeto(&itens,2);
printf("%d\n",itens[0] );
printf("%d\n",itens[1] );
return 0;
}
Hello. I create an array of struct itens and then allocate memory for that array inside the function and fill it. the first element works ([0]) and I can access it outside the function, however, the second never works. What am I doing wrong?
Thanks

You're accessing itens wrong here:
itens[i]->man = i*2;
itens is a pointer to an array of struct item. Instead, do this:
(*itens)[i].man = i*2;
Also, you're printing wrong, too.
Instead of:
printf("%d\n",itens[0] );
printf("%d\n",itens[1] );
use:
printf("%d\n", itens[0].man);
printf("%d\n", itens[1].man);

Related

How to run a function using a function pointer that located in a struct? (C)

I want to create an array of structs based on one struct definition, and initialize each one with a different int value.
Then, I want to print this value, using a function pointer that points to a print function.
Define a struct (includes an int and a function pointer).
create an array of 10 structs of the same definition.
set different values for each one of them.
send this value for a function that is pointed to by a function
pointer that is also located in the struct
This is my code:
#include <stdio.h>
#include <stdlib.h>
#define ARRAY_SIZE 10
void Print(int num);
typedef struct print_me
{
int x;
void (*Print)(int x);
};
struct print_me my_prints[ARRAY_SIZE];
int main()
{
size_t i = 0;
for (i = 0; i < ARRAY_SIZE; ++i)
{
my_prints[i].x = i;
my_prints[i].Print(my_prints[i].x);
}
return 0;
}
void Print(int num)
{
printf("%d\n",num);
}
I'm still learning the ideas of function pointer and structs , so I'll be glad to get some tips and suggestions that will help me to understand my mistakes here.
Thanks.
For starters there is no any sense to use the typedef specifier in this declaration
typedef struct print_me
{
int x;
void (*Print)(int x);
};
without specifying a typedef name. You could write for example
typedef struct print_me
{
int x;
void (*Print)(int x);
} print_me;
In the for loop you need to initialize the data member Print with the address of the function Print. For example
for (i = 0; i < ARRAY_SIZE; ++i)
{
my_prints[i].x = i;
my_prints[i].Print = Print;
}
then in a second for loop you could call the function like
for (i = 0; i < ARRAY_SIZE; ++i)
{
my_prints[i].Print( my_prints[i].x );
}
As with usual pointers, you have to set a pointer value before you can use it. So that it points somewhere.
Add:
my_prints[i].Print = &Print;
// or, it means the same, & is optional
// my_prints[i].Print = Print;
my_prints[i].Print(my_prints[i].x); // now ok
before calling my_prints[i].Print() so that the pointer will point to function Print before calling it.
Side note with a fun fact: because of the strange C rules, dereferencing the function pointer is not needed, and you can even like "dereference" the function pointer multiple times, like (****my_prints[i].Print)(). See ex this question.

Function Returning Pointer to Struct Segmentation Fault

I am working on a project that deals with a struct and has various functions that manipulate the given struct.
I have started off with my initial function that just allocates the memory for the struct, and initialises each item in the struct and then returns a pointer to the struct. I have already defined the struct in my header file. I then have a main file that I will eventually use to run all my functions, however I am having trouble just running this first one, it seg faults every time I run it.
header:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <limits.h>
struct Double_Array{
double** array;
int rowsize;
int colsize;
};
struct Double_Array* double_array(int,int);
function:
#include "header.h"
struct Double_Array* double_array( int row, int col){
int i;
struct Double_Array* ptrDouble_Array;
ptrDouble_Array = (struct Double_Array*) malloc(sizeof(struct Double_Array));
ptrDouble_Array -> rowsize = row;
ptrDouble_Array -> colsize = col;
for(i=0;i< ptrDouble_Array -> colsize ; i++){
ptrDouble_Array -> array[i] = malloc((sizeof(double))*(row));
}
return(ptrDouble_Array);
}
mainline:
#include "header.h"
int main(){
srand(time(0));
printf("running");
int i;
int j;
struct Double_Array* ptr;
ptr = double_array( 5, 5);
for(i=0;i<5;i++){
free(ptr->array[i]);
}
free(ptr);
return(0);
}
I've spent a while looking for possible issues, but everything looks logically correct to me.
What is causing the Seg fault
You're allocating space for each array[i], but you never allocate space for array. So ptrDouble_Array->array[i] is dereferencing an uninitialized pointer, which causes the segfault.
Add the allocation:
ptrDouble_Array->array = malloc((sizeof(double *))*(col));
for(i=0;i< ptrDouble_Array->colsize ; i++){
ptrDouble_Array->array[i] = malloc((sizeof(double))*(row));
}
And don't forget to free it:
for(i=0;i<5;i++){
free(ptr->array[i]);
}
free(ptr->array);
free(ptr);

How to initialize a struct into a pointed struct

Namaste! I want to initialize my struct array position 0 myList.items[0] with a pointer to my item struct, but it prints out jibberish on the relevant positions when I print it out from my print function. It changes what was previously initialized (for test) so I know it works partially, but what's causing the bad output and what should be changed?
Before:
----My Shopping list---------
1 - Chocolate 40 100g
2 - Fishsauce 9 l
After:
----My Shopping list---------
1 - c┴®¶²` 128565603 ■   lüIv
2 - Fishsauce 9 l
typedef struct{
char name[20];
int amount;
char amountType[10];
}item;
typedef struct{
item *items[5];
int length;
}list;
int addItemToList(list *myList);
main(void)
{
list myList;
myList.length = 0;
for(int i; i<5;i++)
{
myList.items[i] = NULL;
}
addItemToList(&myList);
return 0;
}
int addItemToList(list *myList)
{
item newItem = {"Potatoes",2, "kg"};
myList->items[myList->length]=&newItem; //Something wrong here?
myList->length++;
printf ("Added [%s %i %s] as #%i.", newItem.name, newItem.amount,newItem.amountType, myList->length);
return 0;
}
This:
int addItemToList(list *myList)
{
item newItem = {"Potatoes",2, "kg"};
That allocates newItem on the stack. That means the memory for it will go away when addItemToList is completed, so &newItem will be pointing to gibberish later. It will be fine while still running code in addItemToList, but then after that the memory contents will be replaced in any further functions that are called.
You can either use malloc to allocate some memory for newItem, or you can allocate newItem on the stack in your main function and pass the pointer to newItem to any other called functions.
You cannot initialize a struct on the stack and then pass the pointer to that struct to a different struct that lives longer than that stack frame is open. Once the function returns, the stack frame where your item was allocated will close and the assigned values to the fields will be gone.
You need an initializer function with a heap allocated struct like this:
item* item_new(const char* name, int amount, const char* amountType);
Then your initialization function should:
call Malloc for the size of struct,
Copy the name and amountType strings to the struct.
copy the amount to the struct.
Then you can do this: myList->items[myList->length]=newItem;, where newItem is created by your init function.
You are mixing stack and heap memory, I rewriten it for you, it should give you some sense what went wrong. Also always free allocated memory its no java:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
char name[20];
int amount;
char amountType[10];
}item;
typedef struct{
item *items[5];
int length;
}list;
int addItemToList(list *myList);
int main(void)
{
list myList;
myList.length = 0;
for(int i; i<5;i++)
{
myList.items[i] = 0;
}
addItemToList(&myList);
for(int i; i<myList.length; i++)
{
free(myList.items[i]);
}
return 0;
}
int addItemToList(list *myList)
{
item* newItem = malloc(sizeof(item));
strcpy(newItem->name, "Potatoes");
newItem->amount = 2;
strcpy(newItem->amountType, "kg");
myList->items[myList->length++] = newItem; //Something wrong here?
printf ("Added [%s %i %s] as #%i.\n", newItem->name, newItem->amount, newItem->amountType, myList->length);
return 0;
}

How do I return a struct (from a function) containing an array with the correct elements in that array?

I'm making a program that returns a struct containing an array, but the elements in the array are completely wrong. I keep searching for an answer on this site, Google, and even Bing and nothing. The best I can find are answers like this:
Functions can't return arrays in C.
However, they can return structs. And structs can contain arrays...
from How to make an array return type from C function?
Now, how do I fix this without the use of pointers?
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
struct Codes{
int as;
int a[];
};
struct Codes create(int as){
int a[as];
for(int j = 0;j<as;j++)
a[j]=j+1;
struct Codes c;
c.as = as;
c.a[c.as];
for(int i=0; i<as; i++)
c.a[i] = a[i];
for(int i=0; i<as; i+=1)
printf("%d \n", c.a[i]);
return c;
}
int main(int argc, char **argv) {
struct Codes cd;
int as = 4;
cd = create(as);
for(int i=0; i<4; i+=1)
printf("%d \n", cd.a[i]);
}
Actual output:
1
2
3
4
0
0
2
-13120
Expected output:
1
2
3
4
1
2
3
4
structs with flexible value are not meant to be manipulated by value, only by pointer.
You cannot return a struct with a flexible member by value, because C does not know how many items it needs to allocate to the return value, and how many bytes it needs to copy.
Allocate your struct in dynamic memory using malloc of sufficient size, copy your data into it, and return a pointer to the caller:
struct Codes *c = malloc(sizeof(struct Codes)+as*sizeof(int));
c->as = as;
for (int i = 0 ; i != as ; i++) {
c->a[i] = i+1;
}
return c;
Change your function to return a pointer; make sure the caller frees the result.
In your function, struct Codes create(int as), the struct Codes c; is allocated on the stuck, so the memory is no longer valid once the function returns...
...It is true that the core struct is copied in the return value... but the variable array length c.a isn't part of the struct (it's a memory "trailer" or "footer") and isn't copied along with the return value.
Either:
allocate the struct and pass it to a struct Codes create(struct Codes *dest, int as) function; OR
make the struct array fixed in size struct Codes{ int as; int a[4]; };
Good luck.

Assigning Values to Variables Within Structs Through Pointers in C

Ok so I'm sure there's a simple fix that I'm missing, but right now my code is causing a segment fault on the line "A[i]->key = 0;." The Record* Item part is a necessity for the program, so I need to make it work this way for an assignment I'm working on, however if I do change it so that Item becomes a non-pointer typedef of Record, then I can use A[i].key no problem. I just need a nudge in the right direction so that I can make standInput correctly assign values to an array of pointers to records. Thanks!
Item.h:
#include "stdio.h"
#include "stdlib.h"
typedef int keyType;
struct Record
{
keyType key;
int other;
};
typedef struct Record* Item;
void standInput(Item *A, int n)
{
int i, input;
for(i = 0; i <= n-1; i++)
{
A[i]->key = 0;
printf("%d ", A[i]->key);
}
}
Main:
#include "stdio.h"
#include "stdlib.h"
#include "Item.h"
int main()
{
int n;
Item *A;
printf("Enter a length for the array: ");
scanf("%d", &n);
A = (Item*)malloc(n * sizeof(Item));
standInput(A, n);
return 0;
}
The values in A are all uninitialized, but you're using them as struct Record pointers anyway. If you want to have A continue holding pointers (rather than the structs directly), then you need to allocate space for A and for each item pointed to by A.
Note that Item is already a pointer!
You have to allocate space for the struct, not for the pointer:
A = (Item)malloc(n * sizeof(struct Record));
Note: If the typedef for pointer confuses you, don't use it ;)
A[i]->key means that A[i] is a pointer, but you just allocated an array, so use A[i].key.
Note: you have to change the type of A accordingly.
2nd solution: if you want A[i] to be a pointer, you have to fist allocate space for the pointers (as you do now), then for each pointer (in a loop) allocate space for the struct.
Your structure name is Record not Item. So you should use sizeof(struct Record).
Do it this way:
int main()
{
int n, i;
Item *A;
printf("Enter a length for the array: ");
scanf("%d", &n);
A = (Item*)malloc(n * sizeof(Item));
for(i=0; i<n; i++){
A[i] = (Item)malloc(sizeof(struct Record));
}
standInput(A, n);
return 0;
}

Resources