Struct and segmentation fault in c - c

I'm currently new to the struct and linked list. I'm trying to put the values of my array arr_dec[4] in a variable. My array is on a struct, and also in my init function. I think my problem is on the display function, in my if loop.
[EDIT] :
Hi, so I think I correctly changed my errors, but I still get a segmentation fault, and really I don't understand why I get it. If you could see what is wrong and how I can correct it it'll be great ! Thank you.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
typedef struct Plane_dec Element;
struct Plane_dec
{
int array_dec[4];
int nbr_var;
struct Plane_dec *head;
struct Plane_dec *next;
};
void init(int nbr_caract) //It's my initialisation function, i want to initialize my linked list.
{
Element *plane_dec = malloc(sizeof(plane_dec));
Element *head = NULL;
Element *next = NULL;
plane_dec->var_num = 0;
plane_dec->arr_dec[0] = 2;
plane_dec->arr_dec[1] = 5;
plane_dec->arr_dec[2] = 1;
plane_dec->arr_dec[3] = 3;
return *head;
}
void display (int nbr)
{
int i = 0, variable = 0;
struct Plane var;
struct Plane_dec *plane_dec;
init(nbr_caract);
for(i = 0; i <4; i++)
{
variable = plane_dec->arr_dec[i];
printf("%d - ", variable);
}
}
int main()
{
int nbr;
prinft("Please select a number : ");
scanf("%d", &nbr);
display(nbr);
return 0;
}
My output is just : Segmentation fault (core dumped).

Among other problems that prevent compilation:
In display, you pass an uninitialized pointer to a pointer of Plane_dec (you declare a pointer and then pass its address) to init (which is stated to expect just a pointer!), and then within init you attempt to modify its fields.
If what you've been meaning to do is dynamically allocate a Plane_dec, then you need to actually do so: init needs to begin with a *plane_dec = malloc(...), and you need to modify its declaration to accept a pointer to a pointer to Plane_dec, and not just a pointer to Plane_dec.
If, on the other hand, what you've been meaning to do is just modify a local variable declared within display and then discard it when display finishes its run, then you don't want display's plane_dec to be a pointer (so remove the asterisk from the variable declaration).
Either way, the arr_dec you declare within init gets promptly discarded and doesn't have anything to do with the similarly-named field of the plane_dec variable, and nbr_var also doesn't do anything, as it is. (Also note that in display you attempt to access the arr_dec field of Plane_dec, but the field is named array_dec, not arr_dec.)
If this doesn't solve your problem, please make sure to provide more context about what you've actually been meaning to do, as well as post your error (textually, not as an image), and create a minimal reproducible example: make sure to copy the code in question into a brand new file and test that it compiles, and provide the error details based on that. It is quite likely that if you do all of this, you'll figure out the answers on your own; and if you don't, we'll be able to help a lot more efficiently.

Related

Why does a simple assignment generates a segmentation fault in C code?

I may have an error in my code but just by commenting an int asignment that is not even executed is the difference between a segmentation fault and a successfull run of the program. Why does this happen?
C code:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
//keep it > 0
#define DEFAULT_SIZE 50
struct List* init_list();
struct InternalString{
struct List* l;
};
struct List{
struct List * prev;
int max_pos;
int curr_pos;
char value[];
};
typedef struct{
int len;
struct InternalString* __internal__;
} String;
// string constructor
String build(){
String str;
// creates List with an array of max length = DEFAULT_SIZE
struct List* l = init_list(DEFAULT_SIZE);
struct InternalString inter;
inter.l = l;
str.__internal__ = &inter;
str.len = 0;
return str;
}
struct List* init_list(int length){
struct List* l = malloc((length * sizeof(char))+sizeof(struct List));
l->curr_pos = -1;
l->max_pos = length-1;
l->prev = NULL;
return l;
}
void push(char* str, String src){
struct List* l = src.__internal__->l;
int space = l->max_pos - l->curr_pos;
int i = 0;
for (; i < l->max_pos; i++){
if (str[i] == '\0'){
printf("RETURNED\n"); // <---------- Run with the problematic line commented to see that it returns here.
return;
}
l->value[++(l->curr_pos)] = str[i];
}
int needed_space;
//int i_clone = i; // <---------- uncommenting this line provoques the segmentation fault
}
// tests
int main(){
String st = build();
push("defg", st);
}
I'm compiling with gcc 9.4.0 on ubuntu
This means that there is a Memory Access Violation. Sometimes the program can still work, or in other cases not. Even a simple change, like adding a line, can make the difference - between working and Segmentation Fault. Anyway, with or without the line, your code causes such a Memory Access Violation.
You could
write simpler code
search the error by simple methods, like commenting various parts and printf
use debugging tools
Other options:
Just for checking: increase some sizes of allocated memory one after another, and check if there is a difference (might not always help to find the problem)
Allocate more memory, e.g. +2 sizes, one before and one after the end of the used array. Plus write special (unusual) values to the surrounding array elements. Whenever such a surrounding array element is overwritten, that indicates the error then.
In your case, your code does not invite to look at it, at all. Why? It appears to be mixed up to a large extent. Please structure your coding document. Really. (e.g. one part with structures, one with subroutines, not all mixed together)
In build() the variable inter is lost, after leaving build()!
I used
gcc -fsanitize=address,undefined main.c
like provided by very helpful comment.
The indicated memory leak disappears, when defining inter as static by
static struct InternalString inter;
(this might not be what you want, but this indicates were one memory leak is).
I have a question to you, what is this?
struct List* l = malloc((length * sizeof(char))+sizeof(struct List));
If you have a structure, then you allocate the associated structure just by any_number * sizeof(structure). Why do you mix a sizeof(char) into that? Am i missing something - can somebody help? ---> OK, i found this Why is undefined size array in struct allowed? ---> Personal note: Well, I would propose, rather use a fixed array length or, if no upper limit of length is clear, use a pointer.

C error: type name requires a specifier or qualifier

I tried to create a struct that would incude a dynamic array:
typedef struct
{
int idNode;
int* n; //pointer to the int nodes in the dynamically created array of nodes
n = calloc(MAX, sizeof(int)); //dynamic array to store the loser member of the pair
int counter = 0;
}
node;
But I get
error: type name requires a specifier or qualifier
You cannot assign a value to n in the struct declaration. You need to provide a function (something like a constructor ;-) that initializes the structure and assigns a value to its members, including n:
void init_node(node* n)
{
n->idNode = ...;
n->n = calloc(MAX, sizeof(int));
n->counter = 0;
}
Note: you still need to handle errors (e.g. calloc may fail) in the function and propagate errors to its caller.
You can't have statements or initialize an variable inside a structures.
For fix your problem
typedef struct Node {
int idNode;
int* n; //pointer to the int nodes in the dynamically created array of nodes
int counter;
} node;
int main(void)
{
node data = null;
node.n = calloc(sizeof(int), MAX);
node.idNode = 0;
node.counter = 0;
return (0)
}
Now you have initialize your struct
Starting point
I tried to create a struct that would incude a dynamic array
The problem I see in your initial snippet is you mix definition, declaration and use.
From https://www.geeksforgeeks.org/difference-between-definition-and-declaration:
Declaration of a variable is for informing to the compiler the following information: name of the variable, type of value it holds and the initial value if any it takes. i.e., declaration gives details about the properties of a variable. Whereas, Definition of a variable says where the variable gets stored.
Steps to get a basic knowledge of how to do it.
Firstly, you must know how to create a struct.
The next step is how to typedef it.
The next step is how dynamic arrays are declarated, defined, created, stored, modified or destroyed (the life cycle). Pay attention to erros may occur during the execution. The happy path of create things in C is not the only one, there are plenty of errors out there!
The next step is how to insert them into a typedef'd struct.
And the last step is use that typedef struct with a dynamic array inside it. Even you can create multiple dynamic arrays in the struct!
Note: Steps, 1, 2 and 4 may be ordered in other ways depend on the programmer
There is no shortcuts, no trial and error and, of course, you must create test programs to ensure the stuff you want and the stuff you program are the same thing.
n = calloc(MAX, sizeof(int));
int counter = 0;
You cannot use statements to execute inside of the declaration of a structure. You need to initialize n and counter inside of a function after an object of node has been defined.
E.g.:
typedef struct
{
int idNode;
int* n;
int counter;
}
node;
int main (void)
{
node a;
a.n = calloc(MAX, sizeof(int));
a.counter = 0;
}

Accessing the nested Structural Elements

#include<stdio.h>
struct a
{
float n;
int e;
};
struct b
{
struct a *c;
}h;
int main()
{
h.c->n=4;
printf("%f",h.c->n);
return 0;
}
Yes it is small code but I have been trying to access the element e which is instruct a through the struct b. The code is compiled without any error but in the output screen, it is blank.
Please suggest me a good way to access the element in the struct a.
Please note that the struct a has been declared inside the struct b as a pointer.
This would crash because your pointer c was never allocated.
h.c->n=4; // pointer `c` has not been pointing to anything valid
To make it work, you need something like this:
struct a aa; // must allocate an item of struct `a` first
aa.n = 4;
aa.e = 0;
h.c = &aa; // then make pointer `c` to point that that item
printf("%f",h.c->n); // before trying to access that pointer

How to gain access to objects locked behind doublepointer? (C)

In a homework task I must gain access to object specifics (i.e pID, Code), which are located in a structure. However, I need to link my function with the objects first (**ppObjects), but since I am dealing with a doublepointer, I seem to be having an issue.
It is worth noting that when I tried the same commands but function was PrintNewObject(HeaderC* pStruct4) it worked fine - so I am guessing it is an issue with me having to use doublepointer when dealing with pStruct4.
I have provided the code that I have tried below. While compiling it shows no error, but upon trying to print something from it, it says that obj is a nullpointer.
The function that I would like to link with ppObjects.
int InsertNewObject(HeaderC** pStruct4){
HeaderC* testinH;
for (testinH = *pStruct4; testinH != NULL; testinH = testinH->pNext)
{
int count = 0;
while (count < 26) //one for every letter in the alphabet, as ppObjects is an array
{
Object9* obj;
obj = (Object9*)testinH->ppObjects[count]; //the line that does not seem to properly define
printf("%lu", obj->Code); //running this line crashes my program
count++;
}
}
Header, where we can see that ppObjects is a doublepointer.
typedef struct headc
{
void **ppObjects; // Pointer to the array of pointers to objects.
// Objects may be of types Object1-10
char cBegin; // The first letter of ID of objects related to
// header is cBegin.
struct headc *pNext;
} HeaderC;
The object I was provided in the hometask is below. This is what I would get access to after defining
typedef struct ob9
{
char *pID;
unsigned long int Code;
Date3 *pDate3;
struct ob9 *pNext;
} Object9;
I get an error saying that obj is nullpointer when I try to print anything from obj.
If this is poorly worded, I am sorry. I tried my best to make this understandable yet not too long. Any help is appreciated!

Create structure variables in a loop in c

I am trying to create a bunch of struct variables in C.
So lets say I have a for loop which runs 3 times and creates three struct variables.
My question is that why is it creating the variables that reference the same memory location.
Code:
struct arrIndexStruct {
int *arr;
int index;
};
int main() {
int i;
for (i=0; i<3; i++) {
struct arrIndexStruct arrayIndexStruct;
arrayIndexStruct.arr = someArray;
arrayIndexStruct.index = i;
printf("%p\n",(void *)&arrayIndexStruct);
}
}
The output I get is:
0x7ffeed84f690
0x7ffeed84f690
0x7ffeed84f690
Whereas, If I do
struct arrIndexStruct arrayIndexStruct1;
struct arrIndexStruct arrayIndexStruct2;
printf("%p\n",(void *)&arrayIndexStruct1);
printf("%p\n",(void *)&arrayIndexStruct2);
I'll get
0x7ffc484e64d0
0x7ffc484e64e0
What is the difference between the two behaviors and shouldn't for loop have local scope?
Thanks!
The variable is only defined since the first appearance in the code and until the end of its enclosing block. When it reaches end of scope, its original memory can be used anything else.
Specifically in the loop the variables always occupy the same location as it's simply the easiest thing compiler can achieve.
The second case is completely different as the first variable remains defined while the second is introduced. You could get the same address in the following example but it depends on compiler and also debug level, optimization, etc.:
{
struct arrIndexStruct arrayIndexStruct1;
}
{
struct arrIndexStruct arrayIndexStruct2;
}

Resources