segmentation fault (core dumped) gcc ubuntu - c

I was trying to make a simple function to make a group of number that user enters them, using pointer of pointer but i keep getting this error and its hard to tell where the problem is, if there any other option to use something else that tells me where the problem is instead of this weird error.
#include <stdio.h>
void BuildGroub(int** group,int* count){
int i=0;
int j;
printf("Enter the size of the group \n");
scanf("%d", &*count);
while(*count != 0){
printf("Enter the %d number of the group:\n", i);
j=0;
scanf("%d", &**(group+i));
while(**(group+i)!=**(group+j)){
j++;
}
if(j==i){
i++;
count--;
} else{
printf("you have already entered this number please try again: \n");
}
}
}
int main(){
int count;
int group[100];
int *groupptr = &group;
BuildGroub(&groupptr,&count);
for(int i=0;i<count;i++){
printf("%d, ", group[i]);
}
return 0;
}

With this question, you do not need to use double pointer. If you want to learn how to use the double pointer, you can google then there are a ton of examples for you, for example, Double Pointer (Pointer to Pointer) in C.
In BuildGroub you decrease the count pointer
if(j==i){
i++;
count--;
}
, but in the condition of while loop, you compare the value that count pointer points to. it seems strange.
while(*count != 0)
Even if you change count-- to (*count)--, it will decrease the number of elements that you enter to 0 when you get out of the while loop, then in main function:
for(int i=0;i<count;i++){} // count is equal to 0 after calling BuildGroub function if you use (*count--) in while loop.
You should use a temp value for while loop function, for example:
int size = *count;
while(size != 0){
...
if (i == j) {
i++;
size--;
}
}
You should use, for example, group[i] instead of *(group+i). It will be easier to read your code.
The code complete:
#include <stdio.h>
void BuildGroub(int* group,int* count){
int i=0;
int j;
printf("Enter the size of the group \n");
scanf("%d", count);
int size = *count;
while(size != 0){
printf("Enter the %d_th number of the group:\n", i);
j=0;
scanf("%d", &group[i]);
while(group[i] != group[j]) {
j++;
}
if(j==i){
i++;
size--;
} else{
printf("you have already entered this number please try again: \n");
}
}
}
int main(){
int count;
int group[100];
int *groupptr = group;
BuildGroub(groupptr,&count);
for(int i=0;i<count;i++){
printf("%d, ", group[i]);
}
return 0;
}
The test:
./test
Enter the size of the group
5
Enter the 0_th number of the group:
1
Enter the 1_th number of the group:
2
Enter the 2_th number of the group:
2
you have already entered this number please try again:
Enter the 2_th number of the group:
3
Enter the 3_th number of the group:
3
you have already entered this number please try again:
Enter the 3_th number of the group:
4
Enter the 4_th number of the group:
5
1, 2, 3, 4, 5,

If you want to use a double pointer, you need to change your function like this:
void BuildGroub(int** group, int* count) {
int i = 0;
int j;
printf("Enter the size of the group \n");
scanf("%d", &*count); //I think this is redundant but works.
while (*count != 0) {
printf("Enter the %d number of the group:\n", i);
j = 0;
scanf("%d", (*group + i)); //The content of group + i
while ( *( *group + i) != *(*group + j)) { //the content of the content
j++;
}
if (j == i) {
i++;
(*count)--; //The content decrement
} else {
printf("you have already entered this number please try again: \n");
}
}
}
But you have a big problem in main and it is because you are using the parameter count to decrement until zero inside the function. So when the function finish, count value is zero and you don't print anything... You need to change this, using a internal variable to make the count, and finaly, setting the parameter to be using in main.

Related

How to fix 'Segmentation fault' while redirecting input in C

I've searched for solutions to that problem and couldn't find any that match mine.
I wrote a program that gets two arrays of integers and return the scalar product between them. It works fine when I'm submitting the input manually, but when I try to read the input from a text file, I encounter that Segmentation fault.
Edit: I'm talking about stdin redirection
I would be grateful for some help.
The code is:
#include <stdio.h>
#define MAXLIMIT 100
int scalar_product(int[], int[], int);
void set_array(int[]);
int main(){
int arr1[MAXLIMIT], arr2[MAXLIMIT];
int size, result;
set_array(arr1);
set_array(arr2);
printf("Enter the vectors' dimension: ");
scanf("%d", &size);
result = scalar_product(arr1, arr2, size);
printf("The scalar product is: %d \n", result);
return 0;
}
void set_array(int a[]){
int i;
printf("Please enter a vector with up to %d elements: \n", MAXLIMIT);
for (i = 0; i < MAXLIMIT - 1 && (scanf("%d", &a[i]) != EOF); i++);
}
int scalar_product(int a1[], int a2[], int size){
int product = 0, i;
for (i = 0; i < size; i++){
product += a1[i] * a2[i];
}
return product;
}
and the text file contains:
1 -2 3 -4
6 7 1 -2
4
HEre
void set_array(int a[]) {
int i;
printf("Please enter a vector with up to %d elements: \n", MAXLIMIT);
for (i = 0; i < MAXLIMIT - 1 && (scanf("%d", &a[i]) != EOF); i++);
}
When reading from the console you will never hit EOF (unless you enter ctrl-D which I guess you didnt) so your set_array loops just keep going, reading from the file. You read all the data in the first set_array and read nothing in the second one because you have finished the input file
the actualk failure was that you ran off the end of the file, so the scanf of size failed and you were trying to read a random sized array in the function scalar_product.
Test the return from scanf always
What you need to do is put a count in the file before the first array so you know how many items to read into arr1 and I suggest a count before the second lot too.
ie
void set_array(int a[]) {
int i;
int count = 0;
printf("Please enter how many elements you want to enter, max = %d \n", MAXLIMIT);
scanf("%d", &count);
if(count > MAXLIMIT) count = MAXLIMIT;
for (i = 0; i < count && (scanf("%d", &a[i]) != EOF); i++);
}

Why does the C program stop executing after providing 1 element?

I am writing a program to check whether a set is a proper subset of a set or not. I am dynamically allocating memory for both of the sets(arrays) but after I provide one element the program stops executing.
#include <stdio.h>
int setID(int arr[],int arr2[],int size,int size2)
{
int counter =0;
for (int i=0; i<size2;i++)
{
if (arr2[i] == arr[i])
{
counter++;
}
}
if (counter == (size2))
{
return 1;
}
else
return 0;
}
int main ()
{
printf("We are going to check if set A is a proper subset of B or not\n");
printf("Please provide the cardinal number of set A \n");
int a=0,b=0;
scanf("%d",&a);
int *p;
p =(int*) malloc(a*sizeof(int));
printf("Please provide the elements of Set A\n");
for (int i=0;i<a;i++)
{
scanf("%d",p[i]);
}
printf("Please provide cardinal number for set B\n");
scanf("%d",&b);
int *p1;
p1= (int*) malloc(b*sizeof(int));
for (int i=0;i<b;i++)
{
scanf("%d",&p1[i]);
}
printf("Please note that 0 is false and 1 is true\n");
printf("%d\n",setID(p,p1,a,b));
return 0;
}
**Also have I passed the arguments correctly in the function: printf("%d\n",setID(p,p1,a,b)); **
There is one error here
scanf("%d",p[i]);
which should be
scanf("%d", &p[i]);
and which is correct a few lines further down when you did this with p1. You say the program stops after providing one element and this is consistent with the error.
There may be other errors too as posted by others.
in setID :
for (int i=0; i<size2;i++)
{
if (arr2[i] == arr[i])
{
counter++;
}
...
you suppose the size of arr is >= the size of arr2, but this is not mandatory because you read their size rather than to use the same when you allocate the arrays and read their values
if size < size2 (a < b in main) you go out of arr (p in main), the behavior is undefined

Function Crashes Main After Finishing Execution - C

I made this simple program that asks the user to input the number of columns the matrix called arp is going to have because, that way when the program asks the user to input a number so it can find matches on the numbers stored at the array without comparing all 10 columns allocated on memory with array to pointer type.
The problem here comes when the user inputs into the columns size definition 2. All works fine before the last function of p3() does its job, then it doesn't even return to main to execute the infinite loop defined there. I have tried removing the pointers and didn't work; I also tried removing other parts of the code but still nothing...
Update: Tried removing the function to find elements felmnt() and still the same.
Here is The Buggy Code:
#include <stdio.h>
#include <stdlib.h>
int loop = 1;
void keepalive(void)
{
int ckr = 0;
fflush(stdin);
printf("\n\n ******[s]<< CONTINUE | EXIT >>[n]******\n");
while(printf(" > ") && (ckr = getchar()) != 's' && ckr != 'n') fflush(stdin);
getchar();
if(ckr == 'n') loop = 0;
system("CLS");
}
void felmnt(int *colu, int (*arp)[10])
{
int nius=0, colmts, x, i, ejct;
do
{ // loop to let the user find more elements inside matrix
colmts=0;
printf("\n Insert The Number To Find\n > ");
scanf("%d", &nius);
for(x=0; x<*colu; x++) // search of element inside matrix
{
for(i=0; i<=9; i++)
if(nius == arp[i][x])
colmts++;
}
if(colmts>1) // results printing
{
printf("\n %d Elements Found", colmts);
}else if(colmts)
{
printf("\n 1 Element Found");
}else
{
printf("\n Not Found");
}
printf("\n TRY AGAIN? s/n\n > ");
ejct=getchar();
getchar();
}while(ejct=='s');
}
void mat(int *colu, int (*arp)[10])
{
int ci, cn, tst=0;
for(ci=0; ci<*colu; ci++)
{
for(cn=0; cn<10; cn++)
{
printf("\n Input The Number [%d][%d]\n > ", ci+1, cn+1);
scanf(" %d", &arp[cn][ci]);
}
}
printf(" Numbers Inside Matrix> ");
for(ci = 0; ci<*colu; ci++)
{
for(cn=0; cn<10; cn++) printf(" %d", arp[cn][ci]);
}
}
void p3(void)
{ // >>>>main<<<<
int colu=0;
while(loop)
{
printf("\n Input The Quantity Of Columns To Use\n > ");
scanf("%d", &colu);
int arp[10][colu];
mat(&colu, arp);
felmnt(&colu, arp);
keepalive();
}
}
int main(void)
{
int ck = 0, ndx;
while(1)
{ // infinite loop
p3();
fflush(stdin);
printf("\nPause !!!");
getchar();
}
return 0;
}

Trouble storing the size of each array I have in C

I'm having trouble storing the size of each array the user inputs. I need to do this so that I can run different calculations on each set. This is what I'm trying to do now, but it keeps throwing a segmentation fault, and I don't know what I'm doing wrong. The other thing I thought of doing was essentially make one more memory spot with malloc and just store the sizes in another array at the end of the data set arrays. Anyway, here's the code that is giving me a segmentation fault.
int construct_data_sets(int *sets[], int count) {
int set_size;
int j;
j = 0;
printf("Enter the number of elements in data set %d: ", count+1);
scanf(" %d", &set_size);
sets[count] = (int*)malloc((sizeof(int) * set_size));
if (sets[count] == NULL){
printf("Malloc failed!\n");
}
printf("Enter the data for set %d: ", count+1);
while ((j + 1) <= set_size)
{
scanf(" %d", &sets[count][j]);
j++;
}
return set_size;
}
And here's the main, I think the segmentation fault gets thrown when I call construct_data_sets().
int main() {
int command = 0, data_set, set_desired, array_size;
int number = prompt_num_sets();
int *sets[number], i = 0, *sizes[number];
while (i < number)
{
array_size = construct_data_sets(sets, i);
*sizes[i] = array_size;
i++;
}
//printf("The size of the 3rd data set is %d", *sizes[3]);
printf("Data at [data_set][1] = %d\n", sets[data_set-1][1]);
set_desired = select_data_set(number);
while (command != 7) {
printf("Choose what you would like to do:\n");
printf("1. Find the minimum value.\n");
printf("2. Find the maximum value.\n");
printf("3. Calculate the sum of all the values.\n");
printf("4. Calculate the average of all the values.\n");
printf("5. Sort the values in ascending order.\n");
printf("6. Select a different data set.\n");
printf("7. Exit the program.\n");
scanf(" %d", &command);
if (command == 7) {
exit_program();
} else if (command == 6) {
change_term(number, sets);
}
printf("====================================\n");
}
}
Any weird printf statements you may see are just me trying to make sure things are doing what they're supposed to. Let me know if you need more information from me. Thanks.
You have multiple bugs in your code and several stylistic issues. Have you tried running the code in the debugger to see exactly where things are crashing? Have you tried narrowing the code down to a smaller problem?
Your sizes array should have an element type of int instead of int *. You are dereferencing uninitialized memory since you have not allocated anything for the pointers. Your data_set variable is also uninitialized so the array access into sets is also undefined.
You should initialize all of your variables immediately upon definition. Also I would change your code to declare only one variable per statement. The current code is quite difficult to read.
I would also change your initial while loop into a for loop.
Here's a working version that doesn't crash; although, since you haven't included all of the code, I don't know if there are other parts that are broken. I've also had to remove the references to the undefined functions:
#include <stdio.h>
#include <stdlib.h>
int construct_data_sets(int *sets[], int count) {
int set_size;
int j;
printf("Enter the number of elements in data set %d: ", count+1);
scanf(" %d", &set_size);
sets[count] = (int *) malloc((sizeof(int) * set_size));
if (sets[count] == NULL) {
fprintf(stderr, "Malloc failed!\n");
exit(-1);
}
printf("Enter the data for set %d: ", count+1);
for (j = 0; j < set_size; ++j) {
scanf(" %d", &sets[count][j]);
}
return set_size;
}
int main(int argc, char *argv[]) {
int command = 0;
int number = 1;
int *sets[number], i, sizes[number];
for (i = 0; i < number; ++i) {
sizes[i] = construct_data_sets(sets, i);
}
printf("Data at [0][1] = %d\n", sets[0][1]);
while (command != 7) {
printf("Choose what you would like to do:\n");
printf("1. Find the minimum value.\n");
printf("2. Find the maximum value.\n");
printf("3. Calculate the sum of all the values.\n");
printf("4. Calculate the average of all the values.\n");
printf("5. Sort the values in ascending order.\n");
printf("6. Select a different data set.\n");
printf("7. Exit the program.\n");
scanf(" %d", &command);
if (command == 7) {
return 0;
} else if (command == 6) {
return 0;
}
printf("====================================\n");
}
return 0;
}

How to print integers in typing order in C - increasing, decreasing or evenly

I have a problem with a c program I'm trying to write. The program must store integers in array (read from the keyboard). The numbers must be printed out in the order of entering, for example if you enter: 3 2 0 5 5 5 8 9, the ouput should be:
3 2 0 - decreasing
5 5 5 - evenly
8 9 - increasing
The problem for me is, that I can't write an algorithm which to be able to work in all cases.
I was trying to "flag" the elements with another array(using the same index, to save for each integer a value 1-for increasing, -1-for decreasing and 0 for evenly), but this works partly.
Have you any other ideas?
Thanks in advance :)
#include <stdio.h>
#include <stdlib.h>
main() {
int array[100];
int flag[100];
int num, i;
printf("Enter how many numbers you want to type: ");
scanf("%d",&num);
for(i=0;i<num;i++) {
scanf("%d",&array[i]);
}
for(i=0;i<num;i++){
if((array[i]<array[i+1])) {
flag[i]=flag[i+1]=1;
}
if(array[i]>array[i+1]) {
flag[i]=flag[i+1]=-1;
}
}
for(i=0;i<num;i++) {
if(array[i]==array[i+1]) {
flag[i]=flag[i+1]=0;
}
}
for(i=0;i<num;i++){
printf("%d ",flag[i]);
}
printf("\n");
for(i=0;i<num;i++) {
if(flag[i]==1) {
do{
if(flag[i]==1){
printf("%d ",array[i]);
i++;
}
}while(flag[i]==1);
printf(" - increasing\n");
}
if(flag[i]==0) {
do{
if(flag[i]==0){
printf("%d ",array[i]);
i++;
}
}while(flag[i]==0);
printf(" - evenly\n");
}
if(flag[i]==-1) {
do{
if(flag[i]==-1) {
printf("%d ",array[i]);
i++;
}
}while(flag[i]==-1);
printf(" - decreasing\n");
}
}
system("pause");
return 0;
}
Thoughts:
You only know if the 'first' number belongs to a descending, even, or ascending sequence after you see the 'second' number.
The 'third' number either belongs to the same sequence as the first two or is the 'first' number of another sequence.
So: check two numbers and assign a sequence type.
Keep checking numbers in the same sequence.
When you cannot assign the same sequence go back to checking two numbers and assigning a sequence.
Something like
int *n1, *n2, *n3;
n1 = <first element>;
n2 = n1 + 1;
n3 = n2 + 1;
/* some kind of loop */
if ((n3 - n2) HAS_SOME_SIGN_AS (n2 - n1)) /* n3 belongs to the sequence */;
n1++;
n2++;
n3++;
/* end loop */
#include <stdio.h>
int status(a, b){
if(a < b) return 1;
if(a > b) return -1;
return 0;
}
int main() {
int array[100]={0};
int old_status, new_status;
int old_pos;
int num, i, j;
const char* status_message[] = {"decreasing","evenly","increasing", "i don't know"};
printf("Enter how many numbers you want to type: ");
scanf("%d",&num);
for(i=0;i<num;i++)
scanf("%d",&array[i]);
//{num | 1 < num <= 100}
old_status =status(array[0], array[1]);
old_pos = 0;
for(i=1;i<num;++i){
new_status = status(array[i-1], array[i]);
if(old_status != new_status){
for(j=old_pos;j<i;++j)
printf("%d ", array[j]);
printf("- %s\n", status_message[1 + old_status]);
old_status = (i<num-1)? status(array[i], array[i+1]):2;
old_pos = i;
}
}
if(old_pos < num){ //not output section output
for(j=old_pos;j<i;++j)
printf("%d ", array[j]);
printf("- %s\n", status_message[1 + old_status]);
}
return 0;
}

Resources