Segmentation fault (core dumped) in C that includes pointers - c

I am working on a homework project and we are using pointers and it seems that those pointer values are changed at some in my program and I can't find that specific spot. rp is the pointer that is changing. I am new to pointers so I tried de dereferencing them in different ways, but I am ultimately unsure.
Here is my code
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
int getMenuChoice();
void generateCoords(int row, int cols, char[][cols], int *rp, int *cp);
int main() {
int myChoice;
int userDifficulty;
srand(time(NULL));
do {
myChoice = getMenuChoice();
if (myChoice == 1) {
printf("\nEnter difficulty (1, 2, or 3): ");
scanf("%d", &userDifficulty);
int gridSize = 2;
gridSize = userDifficulty * 2;
char array[gridSize][gridSize];
preSetBoard(gridSize, gridSize, array);
generateCoords(gridSize, gridSize, array, x, y);
//printf("%d %d", x, y);
}
} while (myChoice != 0);
return 0;
}
int getMenuChoice() {
int userInput;
printf("***MEMORY!***\n");
printf("1 - Play Game\n");
printf("2 - Check Scores\n");
printf("0 - EXIT\n");
scanf("%d", &userInput);
return userInput;
}
void generateCoords(int row, int cols, char array[][cols], int *rp, int *cp) {
_Bool run = 1;
srand(time(NULL));
while (run) {
int place1 = rand() % (row) + 1;
rp = &place1;
//printf("%d\n", *rp);
int place2 = rand() % (row) + 1;
cp = &place2;
//printf("%d\n", *cp);
if (array[*rp][*cp] == 'A') {
run = 0;
}
}
}
The expected output is a number between 1 and 3.

There are multiple issues in the posted code:
You add 1 to the random numbers generated for coordinates: this may cause the program to try and access the 2D array beyond its boundaries. Index values should be >= 0 and < size.
Furthermore, you do not pass addresses of int variables to generateCoords, but x and y which are not defined within the code posted. This does not really pose a problem since you modify the function arguments to point to local variables.
Here is a corrected version:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int getMenuChoice(void);
void presetBoard(int row, int cols, char[][cols]);
void generateCoords(int row, int cols, char[][cols], int *rp, int *cp);
int main() {
int myChoice, userDifficulty, x, y;
srand(time(NULL));
while ((myChoice = getMenuChoice()) > 0) {
if (myChoice == 1) {
printf("\nEnter difficulty (1, 2, or 3): ");
if (scanf("%d", &userDifficulty) != 1)
break;
int gridSize = userDifficulty * 2;
char array[gridSize][gridSize];
preSetBoard(gridSize, gridSize, array);
generateCoords(gridSize, gridSize, array, &x, &y);
printf("%d %d\n", x, y);
}
}
return 0;
}
int getMenuChoice(void) {
int userInput;
printf("***MEMORY!***\n");
printf("1 - Play Game\n");
printf("2 - Check Scores\n");
printf("0 - EXIT\n");
if (scanf("%d", &userInput) != 1)
userInput = 0;
return userInput;
}
void generateCoords(int rows, int cols, char array[][cols], int *rp, int *cp) {
int col, row;
for (;;) {
row = rand() % rows;
col = rand() % cols;
if (array[row][col] == 'A') {
break;
}
}
/* return found coordinates to the caller */
*rp = row;
*cp = col;
}

Related

I am trying to fix my average for the unopened cases and the display for whether or not the offer is better. How can I do this? I'm not very good at C

Some of my functions aren't working as I want them to, but that really comes down to me not really knowing how to code in C. My bankers_offer function should be calculating the average of unopened cases for the offer, but it always displays a very large number. Also, my printArray should include an option to continue the game after taking a deal, which works, but it isn't continuing the game and offering a new deal, then comparing that deal to the first one.
// comments
//This program is the Deal or No Deal game!
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <locale.h>
#define NBC 27
void swap(int *, int*);
void printArrayEntry(int, char);
void printArray(int *, char *, int);
void randomize(int *, int);
int bankers_offer(int *, char *);
int sum;
int main(int argc, char ** argv) {
int brief_cases[NBC] = {0, 0, 1, 5, 10, 25, 50, 75, 100, 200, 300, 400, 500, 750, 1000, 5000, 10000, 25000, 50000, 75000, 100000, 200000, 300000, 400000, 500000, 750000, 1000000};
int i, j, n;
char deal = 0;
char round_num = 1;
char status[NBC] = {0}; // 0 closed, 1 open, 2 secret brief case
char num_brief_cases;
char playMore = 0;
srand(time(NULL));
setlocale(LC_ALL,"");
printf("Before:\n");
printArray(brief_cases, status, NBC);
randomize(brief_cases, NBC);
printf("\n\nAfter:\n");
printArray(brief_cases, status, NBC);
do {
randomize(brief_cases, NBC);
for (i=0; i<NBC; i++)
status[i] = 0;
printf("Welcome to Deal no Deal Game!\n");
printf("please select a secret brief case: ");
do {
scanf("%i", &n);
if (n < 1 || n > 26)
printf("The number entered is invalid, please choose a different number: ");
} while (n < 1 || n > 26);
status[n] = 2;
do {
//num_brief_cases = (7 - round_num >= 1)?(7-round_num):1;
if (7 - round_num >= 1)
num_brief_cases = 7 - round_num;
else
num_brief_cases = 1;
printf("Let's play round #%i, please open %i brief cases in this round.\n", round_num, num_brief_cases);
for (j = 0; j < num_brief_cases; j++) {
do {
printf("Brief case #%i: ", j+1);
scanf("%i", &n);
if (n < 1 || n > 26)
printf("The number entered is invalid, please choose a different number: ");
else if (status[n] != 0)
printf("The brief case has been opened, please choose a different one: ");
} while ( (n < 1 || n > 26) || (status[n] != 0));
status[n]= 1;
}
//here is where the game is supposed to continue even if a deal is made
//it should then compare the deal of round 2 to the one from round one and say which is better
printArray(brief_cases, status, NBC);
printf("Congratulations! The banker offers $%i\n", bankers_offer(brief_cases, status));
printf("Deal or NO Deal? (0 for no deal, 1 for deal)");
scanf("%i", &deal);
if (deal) {
round_num++;
} else {
}
//} while (deal == 0);
} while (deal);
printf("Play another game?\n");
scanf("%i", &playMore);
} while (playMore);
sum += status[i];
return 0;
}
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
void printArrayEntry(int entry, char status) {
if (status != 1)
printf("$????????");
else {
if (entry == 0)
printf("$0.01 ");
else
printf("$%'-7i", entry);
}
}
void printArray(int *a, char *b, int n) {
int i;
for (i = 1; i <= n/2; i++) {
printf("brief_case[%2i] = ", i);
printArrayEntry(a[i], b[i]);
printf("\t");
printf("brief_case[%2i] = ", i+13);
printArrayEntry(a[i+13], b[i+13]);
printf("\n");
}
}
void randomize(int *a, int n) {
int i;
for (i = n-1; i > 1; i--) {
//int j = rand() % (i+1);
int j = rand()%i + 1;
swap(&a[i], &a[j]);
}
}
//this is where the average is supposed to be calculated but I'm not sure how to do it
//it is supposed to divide unopened cases by the total
int bankers_offer(int *a, char *b) {
int avg;
int sum;
int offer = avg;
// calculate the offer amount here
avg = sum / 26;
return offer;
}

I have a problem with "The 3n+1 problem".when i debug it

I've tried to solve "The 3n+1" problem.
When I debug my code it stuck at line 12, calculation function.
"According to Collatz conjecture, j should converge to 1."
Main file
#include "input_output.h"
#include <stdlib.h>
int main() {
int i=0, j=0;`
int *num;
int maxCycle;
int length;
input(&i, &j);
length = j - i + 1;
num = (int*)malloc(sizeof(int)*(j - i+1));
here is the problem code
while (i <= j) {
calculate(j, num);//<- it stuck at here when i dubug it.
j--;
num++;
}
maxCycle = findMax(length, num);
output(maxCycle);
return 0;
}
source file
#include <stdio.h>
#include "input_output.h"
#pragma warning (disable:4996)
void input(int *i, int *j) {
scanf("%d %d", i,j);
}
void calculate(int j, int* num) {
while (j > 1) {
if (j % 2 == 0) {
j = j / 2;
*num++;
}
if (j % 2 == 1) {
j = j * 3 + 1;
*num++;
}
}
}
int findMax(int length, int * num){
int max = 0;
int idx = 0;
while (idx < length) {
if (*num > max) max = *num;
idx++;
num++;
}
return max;
}
void output(int maxout) {
printf("%d", maxout);
}
Header
#ifndef __input_output_H__
#define __input_output_H__
void input(int *i, int *j);
void calculate(int j,int *num);
int findMax(int length, int* num);
void output(int maxout);
#endif __input_output_H__
I think header seems no problem and also main file.
is there any problem with my source file?
I wonder why debugger stuck at there...
Your loop never ends: you reach j == 1, yet you continue to apply 3n + 1, which makes you go back to 4, and therefore you are in a loop forever:
1 -> 4 -> 2 -> 1 -> ...
By the way, this:
*num++;
is not doing what you think it is doing. You are incrementing the pointer, and then accessing the value (which is not used). So it is as if you had written:
num++;
You should have written (*num)++.
The problem is at j = j * 3 + 1;, 'j' keeps on increasing if 'j' is greater than 1 and odd. So it hangs at calculate(int j,int *num) as the while loop inside it runs infinitely (j value will reset after a while).
Edit:
I have accumulated all the corrections and have added the code:
main.c :
#include "input_output.h"
#include <stdlib.h>
int main()
{
int i=0, j=0;
int *num,*ori; //New pointer required to remember the start position of num
int maxCycle;
int length;
input(&i, &j);
length = j - i + 1;
num = (int*)calloc((size_t)(j-i+1),sizeof(int));
ori=num;
while (i <= j)
{
calculate(j, num);
j--;
num++;
}
num=ori;
maxCycle = findMax(length, num);
num=ori;
output(maxCycle);
return 0;
}
input_output.h :
#ifndef INPUT_OUTPUT_H
#define INPUT_OUTPUT_H
void input(int *i, int *j);
void calculate(int j,int *num);
int findMax(int length, int* num);
void output(int maxout);
#endif
input_output.c :
#include <stdio.h>
#include "input_output.h"
void input(int *i, int *j) {
printf("Enter the i & j:\n");
scanf("%d%d",i,j);
printf("Values entered:\ni: %d\nj: %d",*i,*j);
}
void calculate(int j, int* num) {
while (j > 1) {
if (j==1)
break;
if (j % 2 == 0) {
j = j / 2;
(*num)++;
}
else{
j = j * 3 + 1;
(*num)++;
}
}
printf("\nLength Value: %d\n",*num);
}
int findMax(int length, int * num){
int max = 0;
int idx = 0;
printf("\nLength Values:\n");
while (idx < length) {
printf("%d ",*num);
if (*num > max)
max = *num;
idx++;
num++;
}
return max;
}
void output(int maxout) {
printf("\nResult: %d", maxout);
}
Compile in linux using: gcc input_output.c main.c -Wall -Wextra -pedantic -Wconversion -std=gnu11 -o collatz
For further clarification please comment.

I have an exercise of c

My exercise is input list integer numbers from keyboard and the end of program by 0. Then print sum of array. This is my code:
#include <stdio.h>
#include <stdlib.h>
const int MAX_ITEMS = 50;
void inputIntegerNumber(int* a, int* count);
int sumOfInteger(int* n, int* count);
int main(int argc, char** argv) {
int x[MAX_ITEMS], count;
inputIntegerNumber(&x, &count);
printf("Sum of array is %d", sumOfInteger(&x, &count));
return (EXIT_SUCCESS);
}
void inputIntegerNumber(int* a, int* count ){
do{
printf("Please! input numbers: ");
scanf("%d", a);
*count++;
}while((*a != 0) && (*count != MAX_ITEMS));
}
int sumOfInteger(int* n, int* count){
int sum = 0;
for (int i = 0; i < *count; i++)
sum += *n;
return sum;
}
I don't know what's wrong with it? It doesn't give me a result same my thinks...
There are some problems like -
inputIntegerNumber(&x, &count);
printf("Sum of array is %d", sumOfInteger(&x, &count));
in both calls you pass &x but x is an array of int and your function expects int * not int (*)[]. This must have given an error atleast.
For both functions you can just pass the array x directly.
And in your function inputIntegerNumber this -
*count++;
You need to increment value of count, so it should be (*count)++. Dereference first and then increment the value.
You are doing some mistakes in your code like passing pointer to a pointer &x value(since array is basically a pointer to some memory location) and overwriting the same location again and again. In scanf("%d", a); you are overwriting the first location again and again without changing a in you input loop.You need to learn about arrays and their usage. In sumOfInteger function also you're not changing the value of n. I changed you code a bit and i was able to see desired output.
#include <stdio.h>
#include <stdlib.h>
const int MAX_ITEMS = 50;
void inputIntegerNumber(int* a, int* count);
int sumOfInteger(int* n, int* count);
int main(int argc, char** argv) {
int x[MAX_ITEMS], count = 0; // zero elements in array
inputIntegerNumber(x, &count);
printf("Sum of array is %d", sumOfInteger(x, &count));
return (EXIT_SUCCESS);
}
void inputIntegerNumber(int* a, int* count ){
int aIndex = 0;
do{
printf("Please! input numbers: ");
scanf("%d", &a[aIndex]);
aIndex++;
}while((a[aIndex-1] != 0) && (aIndex != MAX_ITEMS));
*count = aIndex;
}
int sumOfInteger(int* n, int* count){
int sum = 0;
for (int i = 0; i < *count; i++)
sum += n[i];
return sum;
}
when i run it i can see :
~/Documents/src : $ ./a.out
Please! input numbers: 1
Please! input numbers: 2
Please! input numbers: 3
Please! input numbers: 0
Sum of array is 6
You're overcomplicating things. Before you sit down to write a program, always write the general steps that must be done
Read the numbers from the command line
Convert them to ints and save them in memory
Calculate the sum
Print it
Here is the revised program
#include <stdio.h>
#include <stdlib.h> /* for strtol */
#define DIE(msg) fprintf(stderr, "%s", msg); exit(EXIT_FAILURE)
int main(int argc, char *argv[])
{
int *nums;
if (argc <= 1)
DIE("Usage: [int-list]\n");
/* skip program name */
--argc;
++argv;
nums = malloc(argc * sizeof(int));
if (!nums)
DIE("Out of mem\n");
for (int i = 0; i < argc; ++i) {
char *end;
double val = strtol(argv[i], &end, 0);
if (end == argv[i]) /* no digits detected */
DIE("Usage: [int-list]\n");
nums[i] = val;
}
printf("%d\n", add(nums, argc));
free(nums);
}
int add(int arr[], size_t n)
{
int sum = 0;
for (int i = 0; i < n; ++i)
sum += arr[i];
return sum;
}
To complete the strtol error handling is an exercise for the OP.

Create a dynamic array and assign random integer values to it?

int* create_array(char category, int n){
int *a;
a = malloc(n* sizeof(int));
for (int i = 0; i < n; i++) {
int x;
srand( time(NULL));
x = rand();
a[i] = x;
}
When I print this code, it just prints the same random variable 'n' times.
You can use srand(getpid() or you can specify ther range of random numbers using x=rand()%11 generates from 0-10;
You can try something like this:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int *create_array(char category, int n);
int
main(int argc, char const *argv[]) {
time_t t;
int *array;
int i, n;
char category;
srand((unsigned)time(&t));
printf("Enter category: ");
if (scanf("%c", &category) != 1) {
printf("Invalid category.\n");
exit(EXIT_FAILURE);
}
printf("Enter n numbers: ");
if (scanf("%d", &n) != 1) {
printf("Invalid n value.\n");
exit(EXIT_FAILURE);
}
array = create_array(category, n);
printf("Your n random numbers between 0-10:\n");
for (i = 0; i < n; i++) {
printf("%d ", array[i]);
}
free(array);
return 0;
}
int
*create_array(char category, int n) {
int *array;
int i, candidate;
array = malloc(n * sizeof(*array));
for (i = 0; i < n; i++) {
candidate = rand() % 10;
array[i] = candidate;
}
return array;
}

Parallelization of Combination

I have got a piece of code that prints the combination of M number From N (nCm);
As it is a recursion, it works very slow when N is large.
#include <stdio.h>
#include <stdlib.h>
#define N 80
#define M 4
int result[M]= {0}; // THE ARRAY THAT SAVE THE RESULT OF ONE COMBINATION
int queue[N] = {0};
int top = 0;
void comb(int* input,int s, int n, int m)
{
if (s > n)
return ;
if (top == m)
{
for (int i = 0; i < m; i++)
{
result[i] = queue[i];
printf("%d\n", queue[i]);
}
}
queue[top++] = input[s];
comb(input,s+1, n, M);
top--;
comb(input,s+1, n, M);
}
int main()
{
int array[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,
27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,
50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,
73,74,75,76,77,78,79,80};
printf("\ncombination():\n");
comb(array,0, N, M);
printf("\n");
}
I would like to know if there is any space for improvement in the algorithm above?
if possible, can I use openMP ?
Thanks
To me your code was even giving the desired output. see
I have changed
printing format each combination was not good enough.
repeated combinations. (note: else part of if statement added).
reduced 2 recursive call with a loop and a recursive call. (Less space.)
The required code is:
#include <stdio.h>
#include <stdlib.h>
#define N 20
#define M 6
int result[M]= {0}; // THE ARRAY THAT SAVE THE RESULT OF ONE COMBINATION
int queue[N] = {0};
int top = 0;
void comb(int* input,int s, int n, int m)
{
if (s > n)
return ;
if (top == m)
{
printf("\n");
for (int i = 0; i < m; i++)
{
result[i] = queue[i];
printf("%d ", queue[i]);
}
}else{
for(int ss=s;ss<n;ss++){
queue[top++] = input[ss];
comb(input,ss+1, n, m);
top--;
}
//comb(input,s+1, n, m);
}
}
int main()
{
int array[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,
27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,
50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,
73,74,75,76,77,78,79,80};
printf("\ncombinations():\n");
comb(array,0, N, M);
printf("\n");
}

Resources