Segmentation Fault with structs and functions - c

I was having some difficulty in finding and solving a problem with the dreaded segmentation error. I have created a "struct" with an array and filled with with random characters. From there I am counting the horizontal and vertical pairs. Everything seems fine until I run function3(). From there comes the segmentation fault. I ran GDB to find the error, but I do not know why it doesn't work since I have done a similar function for function2() and it is okay with that function. I'm not sure if I am missing a pointer or not. I've played around with adding and subtracting pointers with no luck.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 12
#define COL 15
typedef struct letter_array {
char** letters;
struct letter_array *ltr_ptr;
} larray;
void function1 (larray * letter1);
int function2 (larray * letter2);
int function3 (larray * letter3);
void function4 (int hor_ans, int ver_ans);
int main ( void )
{
larray letter_list;
int vert, hori, count;
letter_list.letters = malloc(ROW*sizeof(int*));
for(count = 0; count<ROW; count++)
{
letter_list.letters [count] = malloc(COL*sizeof(int));
}
printf("\n \t\t\t *** Hello! ***");
printf("\n This program will create a random selection of 180 upper-case"
" characters. \n\n");
function1(&letter_list);
hori = function2(&letter_list);
vert = function3(&letter_list); //The Problem?
free(letter_list.letters);
return ( 0 ) ;
}
void function1 (larray *letter1) // Assign random letters to array.
{
int i, z;
srandom((unsigned)time(NULL));
for(i=0; i<ROW; i++)
{
for(z=0; z<COL; z++)
{
letter1->letters[i][z] = random( )%26+'A';
printf("%c ", letter1->letters[i][z]);
}
printf("\n");
}
return ;
}
int function2 (larray * letter2) //Count horizontal pairs.
{
int a,b;
int m=0;
for(a=0; a<ROW; a++)
{
for(b=0; b<COL; b++)
{
if (letter2->letters[a][b] == (letter2->letters[a][b+1]))
m++;
}
}
return (m);
}
int function3 (larray * letter3) //Count vertical pairs.
{
int a,b;
int n=0;
for (a=0; a<ROW; a++)
{
for(b=0; b<COL; b++)
{
if (letter3->letters[a][b] == (letter3->letters[a+1][b])) //THE Problem..?
n++;
}
}
return (n);
In GDB...
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400ad8 in function3 (letter3=0x7fffffffd8a0)
xxx if (letter3->letters[a][b] == (letter3->letters[a+1][b]))
(gdb) backtrace
#0 0x0000000000400ad8 in function3 (letter3=0x7fffffffd8a0)
#1 0x000000000040088f in main ()
(gdb) up
#1 0x000000000040088f in main ()
xxx vert = function3(&letter_list);
Thank you for your help!

It's pretty obvious. GDB tells you exactly where to look. In your function3 you do
for (a=0; a<ROW; a++)
and then you try to access
letter3->letters[a+1][b]
here, a+1 causes the segmentation fault (you run off the edge of your array).

Related

Passing two arguments

I want to pass two arguments into void Dividing from void Assign_numbers and void Maximum. I have only learnt to pass one argument at a time. Can you please tell me what I have to do print out the following variables inside void Dividing. If it's possible, I don't want the format of my code to change drastically. Can you also show me an example, since I am a visual learner. Thanks
#include <stdlib.h>
#include <stdio.h>
#define Max 6
struct Numbers
{
double a,b,c,d,e,f;
};
void Maximum(double *ptr);
void Dividing(double Maximum, double *ptr);
void Assign_numbers()
{
struct Numbers number;
number.a=45.78;
number.b=81.45;
number.c=56.69;
number.d=34.58;
number.e=23.57;
number.f=78.35;
Maximum((double*) &number);
Dividing((double*) &number);
}
void Maximum(double *ptr)
{
int i=0;
double Maximum = ptr[0];
for(i;i<Max;i++)
{
if(ptr[i]> Maximum)
{
Maximum = ptr[i];
}
}
Dividing(Maximum);
}
void Dividing(double Maximum, double *ptr)
{
printf("%.2f", Maximum);
printf("%.2f",ptr[3]);
}
int main()
{
Assign_numbers();
return 0;
}
Use array instead of struct - shwon here with reference example
Like Joachim Pileborg said. Don't use a struct as an array. In your case use a multidimensional array.
double[10][6] numbers;
You can easily iterate through such an array like so:
#include <stdio.h>
int main () {
/* an array with 2 rows and 6 columns*/
double numbers[2][6] = {
{45.78, 81.45, 56.69, 34.58, 23.57, 78.35},
{1,2,3,4,5, 6}
};
int i, j;
/* output each array element's value */
for ( i = 0; i < 2; i++ ) {
for ( j = 0; j < 6; j++ ) {
printf("numbers[%d][%d] = %f\n", i,j, numbers[i][j] );
}
}
/* Output by reference */
for(i = 0; i < 2; i++){
for(j=0; j < 6; j++ ){
printf("numbers[%d][%d] = %f\n", i, j,*(*(numbers + i) + j));
}
}
return 0;
}
Why the current code fails
Now onto explaining how your code (does not) work and a little about how pointers work. First off:
Dividing(double Maximum, double* ptr);
Does not work in the way you think it does. "double Maximum" is a new double variable that works within the scope of Dividing and is not a variable retrieved from the function:
void Maximum(double *ptr);
If you already knew this, then you should know or at least have expected how poor the naming of your variables are(keep it lowerCamelCase).
Now lets get onto what you're trying to do. IMHO your code is completely broken unless I am noticeing something. In Assign_numbers() you want to call Dividing() using a pointer reference. In Maximum() you want to call Dividing() again, but this time sending only a value. It doesn't make it better that you have 2 separate different calls that each have one parameter. But the function has to have two parameters. Now in order to iterate through the variables in a struct - again this is not recommended and the bottom code only serves as an example.
struct Numbers
{
double a,b,c,d,e,f;
};
struct Numbers Assign_numbers()
{
struct Numbers number;
number.a=45.78;
number.b=81.45;
number.c=56.69;
number.d=34.58;
number.e=23.57;
number.f=78.35;
return number;
}
int main()
{
struct Numbers number;
number = Assign_numbers(number);
double *value = &(number.a); //take address of the first element, since a pointer always counts upwards.
int i;
/*This loops through the addresses of the struct starting from the initial address in number.a and moves upwards 5 times and hopefully ends in number.f. Seriously bad way to construct arrays*/
/*Just try replacing sizeof(number) with sizeof(double). suddenly you get all kinds of weird values because you have ended up outside of the struct*/
/*Also note that this only works when all the datatypes in the struct have a size of 8 bytes(the size of double) */
for (i = 0; i < sizeof(number) / sizeof(double); i++){
printf("[%d]: %f\n",i, value[i]);
}
return 0;
}
New working code
With all that said. This is the closest I am going to to be able to make your code work since I have no idea what you're trying to accomplish:
#include <stdlib.h>
#include <stdio.h>
#define Max 6
struct Numbers
{
double a,b,c,d,e,f;
};
void Maximum(double *ptr);
void Dividing(double *ptr);
void Assign_numbers()
{
struct Numbers number;
number.a=45.78;
number.b=81.45;
number.c=56.69;
number.d=34.58;
number.e=23.57;
number.f=78.35;
Maximum(&number.a); //You need to parse the very first address of the struct. IN this case 'a'
Dividing(&number.a);
}
void Maximum(double *ptr)
{
int i=0;
double maximum = ptr[0];
for(i;i<Max;i++)
{
if(ptr[i]> maximum)
{
maximum = ptr[i];
}
}
printf("maximum: %f", maximum);
}
/*//removed the first parameter since it was not clear what it was for and you only had function calls to this function with one parameter */
void Dividing(double *ptr)
{
printf("%.2f",ptr[3]);
}
int main()
{
Assign_numbers();
return 0;
}

Problems with return value C

Getting problem with return (huge) value. I have already checked at the enthernet, but found nothing :( Hoping that here I could find answer to my question. I am just beginner, so hard to do something right if you dont know what is wrong ((
#include <stdio.h>
#include <math.h>
void MasivaIzveide (int *masivs, int x )
{
int i, reiz,n1,n2;
srand(time(NULL));
/* nosaka cik elementu masiva bus */
printf("Ievadi, divus masiva emelentus, kuri bus '0' starp kuram bus summa\n\n");
printf("\n Pirmais elements=");
scanf("%d", &n1);
printf("\n Otrais elements=");
scanf("%d", &n2);
for ( i = 0; i < x; i++ )
{
masivs[ i ] = rand() % 200-100 ; /* random vertibas katram masiva skaitlim*/
masivs[n1]= 0;
masivs[n2]=0;
printf("Loceklis[%d] = %d\n", i, masivs[i] );
}
return;
}
void Reizinajums (int *masivs, int x) {
int i, reiz;
reiz=masivs[2];
for (i=4; i < x; i=i+2) {
reiz=reiz*masivs[i] ;
}
printf("\n\nReizinajums ir %d\n\n\n\n ", reiz);
return;
}
void main(){
int i,j,s;
int masivs[i];
printf("Tiks izveidots masiivs\n\n\n\n");
MasivaIzveide(masivs,15);
Reizinajums(masivs,15);
return;
}
The problem is at the line (reiz=reiz*masivs[i] ;)
I am using pointers aswell.
Thanks for help.
This is a mistake:
int i,j,s;
int masivs[i];
You are declaring masivs with the dimension i but that is an uninitialized variable. That causes undefined behaviour. Perhaps you meant:
int masivs[15];
You should also check that n1 and n2 are in the correct range before using them as array indices.

Trying to initialize and fill a 2D char array with using structure

What I am trying to do is use a structure to create and display a 2D array of characters in the function 'function1( )'. This array will be sent back to the main( ) so I can use it further in my program. However my program is plagued with problems. I am having trouble with pointers. I assume my problem is somewhere with either my pointers or my variables. I've tried several combinations with no effort. As a beginner, it probably is some odd combination that is not coming to my mind.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 13
#define COL 16
typedef struct letter_array {
char** letters;
struct letter_array *ltr_ptr;
} larray;
void function1 (larray ** letter1[*][16]);
int function2 (larray letter2[][16]);
int function3 (larray letter3[][16]);
void function4 (int hor_ans, int ver_ans);
int main (void)
{
larray letter_list;
int vert, hori, **lptr;
lptr = malloc(ROW*sizeof(int*));
for(vert = 0; vert<ROW; vert++)
{
lptr [vert] = malloc(COL*sizeof(int));
}
printf("\n \t\t\t *** Hello! ***");
printf("\n This program will create a random selection of 180 upper-case"
" characters. \n\n");
function1(&letter_list); //Problem #1
printf("\n\nThank you for using my random character array program. \n"
"\t\t Have a good day! \n");
return ( 0 ) ;
}
void function1 (larray **letter1 [][16])
{
int i, z, funptr;
srandom((unsigned)time(NULL));
for(i=0; i<12; i++)
{
letter1 [i] <- (int*) funptr; // Problem #2-3
for(z=0; z<15; z++)
{
letter1[i][z] = random( )%26+'A'; // Problem #4
printf("%c ", letter1[i][z]);
}
printf("\n");
}
return ;
}
The errors are below and commented.
warning:passing argument 1 of 'function1' from incompatible pointer type
warning: cast to pointer from integer of different size
error: wrong type argument to unary minus
warning: assignment makes pointer from integer without a cast
I hope this helps.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 13
#define COL 16
typedef struct letter_array {
char** letters;
struct letter_array *ltr_ptr;
} larray;
void function1 (larray * letter1); // here you just need a pointer to the structure
int function2 (larray letter2[][16]);
int function3 (larray letter3[][16]);
void function4 (int hor_ans, int ver_ans);
int main (void)
{
larray letter_list;
int vert, hori;
letter_list.letters = malloc(ROW*sizeof(int*)); // allocate memory to the char pointer in the structure
for(vert = 0; vert<ROW; vert++)
{
letter_list.letters[vert] = malloc(COL*sizeof(int)); // allocate the second 2D
}
printf("\n \t\t\t *** Hello! ***");
printf("\n This program will create a random selection of 180 upper-case"
" characters. \n\n");
function1(&letter_list); //Problem #1 pass a pointer to the structure
printf("\n\nThank you for using my random character array program. \n"
"\t\t Have a good day! \n");
return ( 0 ) ;
}
void function1 (larray *letter1) // just needs a pointer to the structure
{
int i, z;
srandom((unsigned)time(NULL));
for(i=0; i<ROW; i++) // used ROW
{
//letter1->letters[i] <- (int*) funptr; // Problem #2-3 this line not needed as near as i can tell
for(z=0; z<COL; z++) // used COL
{
letter1->letters[i][z] = random( )%26+'A'; // Problem #4 dereference pointer to member char **
printf("%c ", letter1->letters[i][z]);
}
printf("\n");
}
return ;
}

Finding Horizontal pairs in a C multidimensional array

I have been struggling for a while with my program. I am trying to find horizontal pairs in an array that is setup in function1. My goal is to change the original array in another function. Then process that array to find a horizontal pair.
One problem that has occurred is when I run the program, the result is zero. Another problem is the gcc warning in function 1, warning: comparison between pointer and integer. The other problem is another gcc warning (marked by the **) warning: passing argument 1 of 'function1' from incompatible pointer type.
I appreciate any help, as a beginner, I have spent several hours on this problem and have tried to find solutions, but trying to use pointers and using struct and typedef have not worked. :(
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void function1 (int letter1[][16]);
void function2 (int letter2[][16]);
int main ( void )
{
int letter_array [13][16];
printf("\n \t\t Hello!");
printf("\n This program will create a random selection of 180 upper-case"
" characters. \n");
**function1(&letter_array);**
function2(letter_array);
return ( 0 ) ;
}
void function1 (int letter1 [][16])
{
int i, z;
srandom((unsigned)time(NULL));
for(i=0; i<=11; i++)
{
for(z=0; z<=14; z++)
{
letter1 [i][z] = random( )%26+65;
printf("%c ", letter1 [i][z]);
}
printf("\n");
}
return ;
}
void function2 (int letter2 [][16])
{
int a,b;
int m=0;
for( a = 0; a <= 11; a++)
{
for( b = 0 ; b <= 14; b++)
{
if (letter2 == (letter2 + 1))
m++;
}
}
printf("\nThe number of horizontal pairs of characters"
" are: %d", m);
return ;
Just remove the ampersand & from the argument.
Change
function1(&letter_array);
to
function1(letter_array);
EDIT:
Also change
if (letter2 == (letter2 + 1))
to
if (letter2[a][b] == (letter2[a][b+1]))
The warning is occurring because you are passing a pointer to an array[][16] into function1 instead of the array itself. This can be resolved by removing the &:
function1(letter_array);
The program is returning 0 because of the return statement at the end of your main function.

segmentation fault during execution of program

I have written a program to create 10 threads and run them normally. The Program is running fine but at the end it gives a segmentation fault. What is this fault, what is causing it, and how do I resolve it?
My code is :
#include<stdio.h>
#include<pthread.h>
void *print(void *num);
int main()
{
pthread_t tid[10];
int n,check;
void *exitstatus;
for(n=1;n<=10;n++)
{
check=pthread_create(&tid[n],NULL,print,(void *)&n);
if(check=0)
printf("thread created");
pthread_join(tid[n],&exitstatus);
}
return 0;
}
void *print(void *num)
{
int i,*val=(int *)num;
for(i=0;i<(5);i++)
printf("Hello World!!!(thread %d )\n",*val);
}
You have many flaws:
for(n=1;n<=10;n++) // No, The array starts from 0 and lasts on 9
Try this
for(n=0;n<10;n++)
if(check=0) // No, this will assign 0 to check instead of compare it
Try this
if(check==0)
You are accessing an array beyond its index. It is undefined behavior.
your array t[10] starts at index t[0] and should end at t[9] -
for(n = 0; n < 10; n++) {
//your stuff
}
Also check == 0 is how you check equality. check = 0 will assign 0 to check
So your code must look like this:
#include<stdio.h>
#include<pthread.h>
void *print(void *num);
int main()
{
pthread_t tid[10];
int n,check;
void *exitstatus;
for(n = 0; n < 10; n++)
{
check=pthread_create(&tid[n], NULL, print, (void *)&n);
if(check == 0)
printf("thread created");
pthread_join(tid[n], &exitstatus);
}
return 0;
}
void *print(void *num)
{
int i,*val=(int *)num;
for(i = 0; i < 5; i++)
printf("Hello World!!!(thread %d )\n", *val);
}
Another important note on programming style: Please use proper indentation and use whitespace judiciously. Most programming errors and bugs can be eliminated if proper indentation and whitespace is used. For example, one white space before and after an operator in the for loop, and between parameters while calling a function after , and before the next parameter.

Resources