Segmentation fault - C language - Struct and For loop - c

I am getting a segmentation fault when i am running the below:
The printf is only for testing the result, as i want to get this info and add it in another array.
#include <stdio.h>
#include <string.h>
struct proion
{
char onoma[30];
float timi;
int stock;
};
int main()
{
int i;
for (i=0;i<=200;i++)
{
struct proion proion[i];
strcpy (proion[i].onoma,"test");
proion[i].timi=5;
proion[i].stock=10;
printf("%s\n%.2f\n%d\n",proion[i].onoma, proion[i].timi,proion[i].stock);
}
return 0;
}

allocate memory In the for loop you are creating an array for Proion.
First loop is:
struct proion proion[0];
So when you access proion[i] you get a segmentation fault since there is no memory allocated for that variable.
This will be also true for other loops because you are access the ith element of the array but you only have 0 to i-1 elements.
The approach is however wrong. Seems like you are trying to create 200 structs. In that case just create the array outside the loop or use malloc to allocate memory dynamically.

You likely mean to say:
struct proion proion[200];
for (i = 0; i < 200; i++)
{
strcpy(proion[i].onoma, "test");
Currently, you're creating a new array each time, e.g. when i == 5, it's like you're saying:
struct proion proion[5];
strcpy (proion[5].onoma,"test");
which will write to the struct just past the end of the array (causing the segmentation fault). And, of course, the whole array is thrown away after every loop.
Also note, in the corrected version, we say i < 200, not i <= 200, if we're working with an array of size 200.

Related

Why am I getting Segmentation fault for using array of char pointers?

I'm trying to play around with c and pointers since I'm new to the language but I'm not sure why I'm getting a segmentation fault, when I have initialized everything to null then going to re-write the array of char pointers? Can someone explain what I did wrong?
#define MAX_SIZE 70
void gridTest(char*[]);
int main()
{
char *grid[MAX_SIZE] = {0};
testGrid(grid);
return 0;
}
void testGrid(char *grid[]){
for(int i=0;i<MAX_SIZE;i++){
*grid[i] = ' ';
}
for(int j=0;j<MAX_SIZE;j++){
printf("The Character is space, test: %c",*grid[j],j);
}
}
ERROR
Segmentation fault: 11
Check this line
*grid[i] = ' ';
you are trying to store the space character in a memory pointed to by grid[i], that's cool, but where does that one point to?
Answer is: Invalid memory (a null pointer, it is). The memory address you're trying to use is invalid and attempt to deference it invokes undefined behavior.
That being said, seeing your usage, you don't need an array of char pointers, an array of char would suffice. Change your array definition to
char grid[MAX_SIZE] = {0};
and change the called function as
void testGrid(char grid[]){
for(int i=0;i<MAX_SIZE;i++){
grid[i] = ' ';
}
for(int j=0;j<MAX_SIZE;j++){
printf("The Character is space, test: %c",grid[j],j);
}
}
By declaring an array of char pointers, you become responsible for making those pointers point to something. If you just want to get a 70x70 grid, you can get around that by declaring grid as an array of char arrays:
char grid[MAX_SIZE][MAX_SIZE];
That way, the memory is automatically allocated and ready for use.
*grid[i] is equivalent to grid[i][0], so testGrid currently accesses only the first column in each row. To access all cells in the grid, you could use two nested for loops and access them with grid[i][j] or similar.

Using a multidimensional array within a structure [duplicate]

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.

Segfaults and referencing struct arrays

I've got a project that involves creating a text game. I'm creating a struct for each player and putting them in an array. I'm then trying to pass in data and then pass by pointer the array to other functions, however I keep on getting segmentation faults (Although on the odd occasion working fine). I've summarised below.
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
char name[9];
int cardsHeld;
int hand[8];
} Player;
void printNames(Player** playerArray)
{
for (int i = 0; i < 3; i++)
{
fprintf(stdout, "%s\n", playerArray[i]->name);
}
}
void gamesetup()
{
int count;
fprintf(stdout, "How many players will be partaking in 'The Game'? ( 1 - 5)\n");
fscanf(stdin, "%d", &count);
Player** playerArray = (Player**)malloc(sizeof(Player*) * count);
for(int i = 0; i < count; i++)
{
playerArray[i] = (Player*) malloc(sizeof(Player));
fprintf(stdout, "Please enter the name for player %d.\n\n", i + 1);
fscanf(stdin, "%s", playerArray[i]->name);
}
printNames(playerArray);
}
int main(int argc, char** argv)
{
gamesetup();
return 0;
}
My questions are;
Is the fscanf getting the address of the Player.name member? I'm getting confused whether the -> operator should deference the value of the struct member or since its in an array the address?
I'm not sure why it works sometimes but not others. If it works sometimes fundamentally it should be ok. Is the malloc function allocating memory it should not or is the fscanf putting data in the wrong place.
Thank you.
-EDIT-
Changed the code so it is in a complete program that appears to work without seg faults. I think that my issues arise from not freeing the memory before termination is messing it up next time I run it without compiling first. I'm still not sure why fscanf works as in my mind the argument playerArray[i]->name is returning the value, not the address.
I've worked it out where I was confused. Thank you for all your help in the comments.
The member I am accessing in my array is a string of chars so the first member is a pointer. By using fscanf(stdin, "%s",playerArray[i]->name); This deferenced the pointer (an address) so it works. I was getting in a muddle as it was an member of an array of structs. The segfaults were caused by me messing with the code to try and fix what already worked.

Passing uninitialized 2D arrays as arguments in C

all. I've tried and tried to get my head around this, and feel I am almost there, but I'm getting so confused with how many '*' I need! I have a function that takes as input the string of a directory containing a data file, an int and pointers to two uninitialized 2D arrays. The function reads the data file and then allocates memory and fills the arrays accordingly.
This code is completely wrong, I know, but the idea is:
void main()
{
double **Array1;
int **Array2;
int dimension1;
char DirWork[100], buff[100];
f_ReadData(DirWork, dimension1, &Array1, &Array2);
sprintf(buff,"%lf",Array1[0][0]); // Causes segmentation fault
printf(buff);
}
and
void f_ReadData(char *DirWork, int dimension1, double ***Array1ptr, int ***Array2ptr)
{
int ct, ct2;
double **Array1 = *Array1ptr;
int **Array2 = *Array2ptr;
char FullDirArray1[100], FullDirArray2[100];
FILE *d_Array1, *d_Array2;
sprintf(FullDirArray1,"%s%s,DirWork,"Array1.dat");
sprintf(FullDirArray2,"%s%s,DirWork,"Array2.dat");
d_Array1=fopen(FullDirArray1,"r");
d_Array2=fopen(FullDirArray2,"r");
fscanf(d_Array1,"%d", &dimension1);
Array1 = dmatrix(0,dimension1-1,0,3); // allocates memory to Array1 (dimension1 x 3) elements, using nrutil
Array2 = imatrix(0,dimension1-1,0,3); // allocates memory to Array2 (dimension1 x 3) elements, using nrutil
for(ct=0; ct<dimension1; ct++)
{
for(ct2=0; ct2<3; ct2++)
{
fscanf(d_Array1, "%lf", &Array1[ct][ct2];
fscanf(d_Array2, "%d", &Array2[ct][ct2];
}
}
fclose(d_Array1);
fclose(d_Array2);
}
I've missed out error handling here, but I do have some of that in place... not that it's helping. I'm getting a segmentation fault when I try to access the arrays from the main function.
If anyone could help, I'd really appreciate it... I'm seeing *stars! Thank you!
Then number of stars is correct.
You are getting a segfault because you don't copy back the pointer to the buffers that you allocated. You initialize only f_ReadData:Array1 but you need to assign this value back to *Array1ptr.

Why does this give a segmentation fault?

I'm stunned, why does this code give me a segmentation fault?
#include <stdio.h>
#define LIMIT 1500000
typedef struct {
int p;
int a;
int b;
} triplet;
int main(int argc, char **argv) {
int i;
triplet triplets[LIMIT];
for (i = 0; i < LIMIT; i++) {
triplets[i].p = 9; // remove this line and everything works fine
}
printf("%d\n", triplets[15].p);
return 0;
}
EDIT: After changing LIMIT to 150 I no longer get a segmentation fault, it prints random numbers instead.
EDIT2: Now I know what the site name stands for :) I made the array global and everything works fine now.
Stack overflow! Allocating 1500000 records at 12 bytes per record (assuming 4-byte int), requires more than 17 MB of stack space. Make your triplets array global or dynamically allocate it.
As to your edit - shrinking the array will probably stop the stack overflow, but your printf() call will still print uninitialized data - triplets[15].p could be anything at the time you print it out.
When you do
triplet triplets[LIMIT];
you're allocating that on the stack. Which is apparently too big for your system.
If you do
triplet* triplets=(triplet*)malloc(LIMIT*sizeof(triplet));
you'll allocate it on the heap and everything should be fine. Be sure to free the memory when you're done with it
free(triplets);

Resources