This question already has answers here:
How to initialize a pointer to a struct in C?
(7 answers)
My linked list results in segmentation fault every time even though I cannot see a flaw
(2 answers)
Closed 10 months ago.
This program keep crashing after printing first 'ok'. I am running it on VS Code using g++ compiler.
#include<stdio.h>
#include<stdlib.h>
struct rod {
char name;
int *list;
int index;
};
int main()
{
int n=3;
struct rod *rodA, *rodB, *rodC;
rodA->name = 'A';
printf("ok");
rodB->name = 'B';
printf("ok");
rodC->name = 'C';
printf("ok");
rodA->list = (int*) calloc(n, sizeof(int));
rodB->list = (int*) calloc(n, sizeof(int));
rodC->list = (int*) calloc(n, sizeof(int));
}
This line declares three pointer variables, but never initializes them.
struct rod *rodA, *rodB, *rodC;
Then this line corrupts memory because you never set the pointers to a valid memory address:
rodA->name = 'A';
After that, the behavior of the program is 'undefined' and eventually will crash.
That is because of memory violation. You create pointers that point to nothing (garbage). One of them seems to point to read-only memory, and when you try to assign something to it, program crashes. Try allocating them like this:
struct rod *rodA = calloc(1, sizeof(struct rod));
Related
This question already has answers here:
Crash or "segmentation fault" when data is copied/scanned/read to an uninitialized pointer
(5 answers)
Closed 5 years ago.
I have written the following code:
#include <stdio.h>
#include <stdlib.h>
typedef struct _NeuralNetwork{
int input_rows;
int input_columns;
double **inputs;
}NeuralNetwork;
void main(){
// structure variable
NeuralNetwork *nn;
int count;
int i,j;
nn->input_rows = 2;
nn->input_columns = 3;
// create the array of double pointers using # of rows
nn->inputs = (double **)malloc(nn->input_rows * sizeof(double *));
// each pointer gets an array of double values
for (i=0; i<nn->input_rows; i++){
nn->inputs[i] = (double *)malloc(nn->input_columns * sizeof(double));
}
// assign values
count = 0;
for (i = 0; i < nn->input_rows ; i++)
for (j = 0; j < nn->input_columns; j++)
nn->inputs[i][j] = ++count;
// print those values
for (i = 0; i<nn->input_rows; i++)
for (j = 0; j < nn->input_columns; j++)
printf("%f ", nn->inputs[i][j]);
/* Code for further processing and free the
dynamically allocated memory*/
return;
}
When I compile this everything is okay. But after running it, I get a segmentation fault error:
Segmentation fault (core dumped)
I am not sure, where the mistake is. Can somebody help?
Note: When I use nn as structure variable instead of a structure, then everything is fine. But I want to use it as structure pointer and access the structure members via "->" and not via "." since I plan to pass nn as pointer to another function later.
Thank you in advance :)
The variable nn is a pointer, but that pointer is never initialized. You subsequently read and dereference that pointer using an operation such as nn->input_rows = 2;. This invokes undefined behavior.
In this particular case, nn likely contains some garbage value. By dereferencing that pointer value, you are attempting to read from memory you probably aren't allowed to. This is what causes the crash.
By defining nn as an instance of a struct instead of a pointer, as you said you tried, you avoid this issue. You can still however pass a pointer to other functions by taking the address of this variable and passing that to the function, i.e.:
NeuralNetwork nn;
...
myfunction(&nn)
First, do not use void main(), it's non-standard and would eventually cause problems. The right way is int main() or int main(int argc, char** argv). Remember to return a proper value at the end of the main function, possibly 0. Consult the reference here: main function
Second, if you use NeuralNetwork *nn; you must allocate some space for it in memory. It's a pointer to some memory address, if you don't allocate it who knows where it points. That's why you're getting the segfault. You must allocate memory for it in the following way:
NeuralNetwork *nn = malloc(sizeof(NeuralNetwork));
Then it should work properly.
This question already has answers here:
How much memory would be freed if pointer is changed in C?
(3 answers)
Closed 5 years ago.
I have written the following code, however I get a crash (without warnings or errors) and do not know the cause:
const int N = 1000;
int main(){
int *pI = calloc(N,sizeof(int));
for (int i=0;i<N;i++) {
*(pI++) = (i+1);
}
free(pI);
return EXIT_SUCCESS;
}
I am thankful for any advice!
You are not releasing the original pointer received from calloc():
free(pI);
You have been modifying the value contained in this pointer:
*(pI++) = (i+1);
Do instead:
int *p = calloc(N,sizeof(int));
int *pI = p;
// ...
free(p);
That is, save the value returned from calloc() and then pass it to free() when you don't need the allocated memory anymore.
This question already has answers here:
C++ SegFault when dereferencing a pointer for cout
(5 answers)
Definitive List of Common Reasons for Segmentation Faults
(1 answer)
Closed 5 years ago.
I'm working on a project and trying to perform a similar operation as given below, but getting segmentation fault error. I don't understand why it is giving this error, even though I assigned the memory using malloc. Any help on this error is appreciated.
#include <stdio.h>
struct hello{
int i;
};
struct proc{
int j;
struct hello *hello[20];
};
int main()
{
struct proc *proc;
proc->hello[0] = malloc(sizeof(struct hello));
proc->hello[0]->i =10;
printf("value of i: %d\n",proc->hello[0]->i);
return 0;
}
It would be best practice for you to give your variables names separate from their typing.
so
struct proc *proc;
I would recommend something like
struct proc *my_proc;
However, the reason why you're seg faulting is that you're trying to access your *proc before it has been allocated any memory.
It might be NULL, but, more likely, it contains the memory address of a value equal to whatever left over memory is occupying the space that you should be storing a memory address.
So is it we assume it is NULL then what you have programmed is saying
Start Program
Give me a pointer at NULL
Go to NULL and malloc
-- SEG FAULT--
You just need to malloc your *proc
int NUM_PROC = 1;
struct proc *my_proc = malloc(sizeof(struct proc) * NUM_PROC);
I came across a concept which some people call a "Struct Hack" where we can declare a pointer variable inside a struct, like this:
struct myStruct{
int data;
int *array;
};
and later on when we allocate memory for a struct myStruct using malloc in our main() function, we can simultaneously allocate memory for our int *array pointer in same step, like this:
struct myStruct *p = malloc(sizeof(struct myStruct) + 100 * sizeof(int));
p->array = p+1;
instead of
struct myStruct *p = malloc(sizeof(struct myStruct));
p->array = malloc(100 * sizeof(int));
assuming we want an array of size 100.
The first option is said to be better since we would get a continuous chunk of memory and we can free that whole chunk with one call to free() versus 2 calls in the latter case.
Experimenting, I wrote this:
#include<stdio.h>
#include<stdlib.h>
struct myStruct{
int i;
int *array;
};
int main(){
/* I ask for only 40 more bytes (10 * sizeof(int)) */
struct myStruct *p = malloc(sizeof(struct myStruct) + 10 * sizeof(int));
p->array = p+1;
/* I assign values way beyond the initial allocation*/
for (int i = 0; i < 804; i++){
p->array[i] = i;
}
/* printing*/
for (int i = 0; i < 804; i++){
printf("%d\n",p->array[i]);
}
return 0;
}
I am able to execute it without problems, without any segmentation faults. Looks weird to me.
I also came to know that C99 has a provision which says that instead of declaring an int *array inside a struct, we can do int array[] and I did this, using malloc() only for the struct, like
struct myStruct *p = malloc(sizeof(struct myStruct));
and initialising array[] like this
p->array[10] = 0; /* I hope this sets the array size to 10
and also initialises array entries to 0 */
But then again this weirdness where I am able to access and assign array indices beyond the array size and also print the entries:
for(int i = 0; i < 296; i++){ // first loop
p->array[i] = i;
}
for(int i = 0; i < 296; i++){ // second loop
printf("%d\n",p->array[i]);
}
After printing p->array[i] till i = 296 it gives me a segmentation fault, but clearly it had no problems assigning beyond i = 9.
(If I increment 'i' till 300 in the first for loop above, I immediately get a segmentation fault and the program doesn't print any values.)
Any clues about what's happening? Is it undefined behaviour or what?
EDIT: When I compiled the first snippet with the command
cc -Wall -g -std=c11 -O struct3.c -o struct3
I got this warning:
warning: incompatible pointer types assigning to 'int *' from
'struct str *' [-Wincompatible-pointer-types]
p->array = p+1;
Yes, what you see here is an example of undefined behavior.
Writing beyond the end of allocated array (aka buffer overflow) is a good example of undefined behavior: it will often appear to "work normally", while other times it will crash (e.g. "Segmentation fault").
A low-level explanation: there are control structures in memory that are situated some distance from your allocated objects. If your program does a big buffer overflow, there is more chance it will damage these control structures, while for more modest overflows it will damage some unused data (e.g. padding). In any case, however, buffer overflows invoke undefined behavior.
The "struct hack" in your first form also invokes undefined behavior (as indicated by the warning), but of a special kind - it's almost guaranteed that it would always work normally, in most compilers. However, it's still undefined behavior, so not recommended to use. In order to sanction its use, the C committee invented this "flexible array member" syntax (your second syntax), which is guaranteed to work.
Just to make it clear - assignment to an element of an array never allocates space for that element (not in C, at least). In C, when assigning to an element, it should already be allocated, even if the array is "flexible". Your code should know how much to allocate when it allocates memory. If you don't know how much to allocate, use one of the following techniques:
Allocate an upper bound:
struct myStruct{
int data;
int array[100]; // you will never need more than 100 numbers
};
Use realloc
Use a linked list (or any other sophisticated data structure)
What you describe as a "Struct Hack" is indeed a hack. It is not worth IMO.
p->array = p+1;
will give you problems on many compilers which will demand explicit conversion:
p->array = (int *) (p+1);
I am able to execute it without problems, without any segmentation faults. Looks weird to me.
It is undefined behaviour. You are accessing memory on the heap and many compilers and operating system will not prevent you to do so. But it extremely bad practice to use it.
This question already has answers here:
Using malloc for allocation of multi-dimensional arrays with different row lengths
(8 answers)
Closed 9 years ago.
I have a structure to store information in a 2D array:
struct slopes {
int size;
int ** slope_array;
};
I malloc the required memory for the structure(the array has dimensions of s*s):
struct slopes * slope=malloc(sizeof(struct slopes));
slope->size=s;
slope->slope_array=malloc(sizeof(int *)*s);
int i;
for(i=0;i<s;i++) {
slope->slope_array=malloc(sizeof(int)*s);
}
But lines such as these seem to throw segmentation errors:
slope->slope_array[0][0]=3;
Can someone see what I'm doing wrong?
In your for loop, you need to initialize slope->slope_array[i], not slope->slope_array:
for (i = 0; i < s; i++) {
slope->slope_array[i] = malloc(sizeof(int)*s);
}
Note: if you had cast the return call from malloc to an int *, the compiler would have warned you about this error...
There is a simple bug in your code, in the for loop do not assign the pointer returned by malloc to slope->slope_array, but to slope->slope_array[i]
slope->slope_array[i] = malloc(sizeof(int) * s);