Beginner Here Rand in c - arrays

im a 1st grader when it comes to c and need help with storing 5 random values in an array and outputting them. Heres where am at.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
struct score_card {int A_ones; int B_twos; int C_threes; int D_fours; int E_fives; int F_sixes; int G_chance;};
int dice_rolls[5];
int randomize(void);
int value;
int main(void) {
struct score_card test;
randomize;
int i;
for(i = 0; i <= 4; i++){
printf("%d\n", dice_rolls[i]);
}
printf("\n");
return 0;
}
int randomize(void){
int i;
srand(time(0));
for(i = 0; i <= 4; i++){
value = rand() % 6 + 1;
dice_rolls[i] = value;
}
}
The output is :
6294304
6294308
6294312
6294316
6294320
the goal was to use modular division to get values from 1 -->6 and store them in the dicerolls array.

I see two immediate problems.
First. you're not terminating your random numbers with a newline. That's why they're all strung together in a big sequence. Change your output line to:
printf("%d\n", &dice_rolls[i]);
Secondly, you're not actually calling randomize. The correct way to call it is with:
randomize();
The statement randomize; is simply an expression giving you the address of the function. It's as useless in this case as the expression 42; which also does nothing. However it's valid C so the compiler doesn't necessarily complain.

Related

C Segmentation Fault from function that returns the maximum of an array

I just have a function that finds out the maximum value of an array of integers, but I get a segmentation fault, which I can't find because the compiler doesn't show me the line of the error.
This is my C code:
#include <stdlib.h>
#include <stdio.h>
//Funktion ermittelt den größten Wert eines Arrays
int groesstesElement(int **arrayPointer){
int max = 0;
for (int i = 0; i < 3; i++) {
if (*arrayPointer[i]>max) {
max = *arrayPointer[i];
}
}
return max;
}
int main (int argc, char **argv) {
int array[4]={1,2,3,4};
int *ptr = array;
int z = groesstesElement(&ptr);
printf("%d\n", z);
return EXIT_SUCCESS;
}
I use macOS and VSC.
In C, array indexing [] has higher precedence than pointer de-referencing *: https://en.cppreference.com/w/c/language/operator_precedence
Some parentheses fix the segfault.
if ((*arrayPointer)[i]>max) {
max = (*arrayPointer)[i];
}
Due to the operators precedence, with
*arrayPointer[i]
you are telling your program:
Take the i-th element of the array arrayPointer and dereference it.
But arrayPointer is a pointer to int *, so all you get is the address of ptr (the int ** pointer defined from main) with an offset. When you finally dereference it you are likely accessing an invalid address, causing segmentation fault.
As already suggested by the main answer, the fix is done using parenthesis in order to apply the operators in the order you want:
(*arrayPointer)[i]
Secondary issues in the code
Even though with the correction above the program won't crash anymore, it won't work. Searching through the array with the loop
for (i = 0; i < 3; i++)
you won't include the last item in the search (index 3), skipping precisely the index that, in your example, contains the maximum value. You probably meant for (i = 0; i < 4; i++) or for (i = 0; i <= 3; i++).
Anyway, using magic numbers in the code (in this case the dimension of the array) is considered bad practice. A better solution would have been using a #define, but an even better solution would have been passing to the function the size of the array:
#include <stdlib.h>
#include <stdio.h>
#define ARR_SIZE 4
//Funktion ermittelt den größten Wert eines Arrays
int groesstesElement(int *arrayPointer, unsigned int arrSize){
int max = 0, i;
for (i = 0; i < arrSize; i++) {
if (arrayPointer[i]>max) {
max = arrayPointer[i];
}
}
return max;
}
int main (int argc, char **argv) {
int array[ARR_SIZE]={1,2,3,4};
int z = groesstesElement(array, ARR_SIZE);
printf("%d\n", z);
return EXIT_SUCCESS;
}
Please note how there's no need to use a double pointer anymore.

Changing the value of a variable with pointers not working

Basically I have a function called MinSubTab that is supposed to calculate the sum of the array passed and also to change the value passed in the first argument from inside the function without using return. This is done with pointers. Anyway, I think it'd be easier if I just showed you the code so here it is:
maintab.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "tab.h"
int main(){
int *reftab;
int min;
reftab = (int *)malloc(sizeof(int) * NMAX);
InitTab(reftab,NMAX);
printf("\n Total: %d et min: %d", MinSumTab(&min, reftab, NMAX), min);
free(reftab);
return 0;
}
tab.c
void InitTab(int *tab, int size){
srand(time(NULL));
for (int i=0; i<size; i++){
*(tab+i) = rand() % 10;
}
}
int MinSumTab(int *min, int *tab, int size){
int total=0;
int minimum = NMAX;
int temp = *min;
for (int i=0; i<size; i++){
total += *(tab+i);
}
for (int i=0; i<size; i++){
if(*(tab+i)<minimum){
minimum = *(tab+i);
}
}
*min = minimum;
return total;
}
So the expected result here is that the sum is printed (which it is) and the minimum value of the array is printed (which it is not). Every single time the min variable equals 8 and I've no idea how to actually change the value of min from within that function.
Please help as my brain has no more capacity for rational thought, it's been 1.5 hrs and no solution in sight. Thanks
Looks like a small mistake:
You initialize minimum with NMAX, which I assume is 8 (the size of the array). 99.9% of the random numbers will be bigger. So 8 is chosen as the minimum.
What you really want is to initialize it with RAND_MAX – the maximum value rand() can return.
In C order of evaluation and argument passing is undefined.
You can of course the order yourself but it only to feed your curiosity.
#include <stdio.h>
volatile char *message[] = {
"fisrt", "second", "third", "fourth"
};
int print(size_t x)
{
printf("%s\n", message[x]);
return x;
}
int main()
{
printf("%d %d %d %d\n", print(0), print(1), print(2), print(3));
return 0;
}
Note. There is one exception from this rule.
Logical operators are evaluated form the left to the right.
if( x != NULL && *x == 5)is safe because x will not be dereferenced if it is NULL

C: segmentation fault when running function from another file

When ever i run this code, it works up until i get to the printf statement in my main function, thats when i get a segmentation fault error. so it will run like "enter how many numbers you want" 3 "Enter the numbers in the array" 1 2 3 array[0] = 1 array[1] = 2 array[2] = 3 segmentation error. Can you guys please tell me why im getting this error and how to fix it? thank you
//pathfinder.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Vector.h"
int main()
{
Vector *V;
VectorRead(V);
printf("%d", V->item[0]);
return 0;
}
//Vector.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
typedef struct{
int *item;
int size;
} Vector;
void VectorRead(Vector *V) ;
void VectorRead(Vector *V)
{
int N;
printf("Enter how many numbers you want?\n");
scanf("%d", &N);
V = (Vector *)malloc(sizeof(Vector *) * N);
V->size = N;
V->item = (int *)malloc(sizeof(int *) * V->size);
printf("Enter the numbers that you want in your array\n");
int i = 0;
while(i < V->size && scanf("%d", &(V->item[i++])) == 1);
int j;
for(j = 0; j< V->size; j++){
printf("array[%d]=%d\n", j, V->item[j]);
}
}
This error has nothing to do with your code being in different files.
When you call VectorRead(), you are passing a pointer value. Inside that function, you are setting the local V to the return value of a call to malloc(). There is no way for that local V to return back to the caller.
You will need to do something to return the newly allocated value of V back to the caller. Changing your function to return a Vector * (instead of taking one as a parameter) would be a good approach.
Your local Vector, V, is not being modified when VectorRead() is called. Try instead accepting a Vector ** in your function:
void VectorRead(Vector **V)
and modify the function accordingly.
Or, since your function has no return value, and as #EOF points out in the comments, it is probably a better idea to not take a parameter, and simply return the Vector *:
Vector *VectorRead(void)

Command line number adding program produces wrong results

My Code:
#include <stdio.h>
int main(int argc, char*argv[]){
int n = argc;
int i, a, b, sum;
for(i = 0; i < n; i++){
sscanf(argv[i], "%u", &a);
b = a + sum;
sum = b;
}
printf("%d\n", sum);
return 0;
}
This piece of code should do ./a 0 1 2 3 must write terminal 6 But writes 42423.
The aim of the program was to issue the command-line arguments amount. But he does not make it correct angulation.
argv[0] holds the name of the executable which most likely you don't want to include in the loop. so, you need to start the loop from i=1.
As per your input, the argv[0] does not contain a numeric value hence causing a failure to sscanf(), leaving a uninitialized.
So, in your code, the primary issue is with,
b = a + sum;
where, for the first iteration, a and sum are both uninitialized local variables having indeterminate value. So, for the very first loop, you're invoking undefined behavior.
Also, a being an int, you need to use %d format specifier for it.
Two things to mention:
Always check for the return value of scanf() family for success.
Always initialize your local variables.
You are getting garbage value because you are not initialized varuiable sum on declaration.
Just initialize is as sum = 0 and u will get expected result.
Or u can use below code also.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char*argv[]){
int n = argc;
int i, a, b, sum=0;
for(i = 0; i < n; i++){
a = atoi(argv[i]);
sum += a;
}
printf("%d\n", sum);
return 0;
}

Code crashes at the printf statement

The code runs until it reaches the statement:
printf("%d", sumOccur(input));
The code:
#include <stdio.h>
#include <stdlib.h>
int sumOccur(int A[]);
int main(){
int input[6] = {1,1,1,2,2,3};
printf("%d", sumOccur(input));
return 0;
}
int sumOccur(int A[]) {
int sum, i;
while(A[i]!='\0'){
sum += A[i];
i++;
}
return sum;
}
If I have made any silly mistakes please oblige.
It's not the printf() crashing. It's sumOccur(). Your array has no \0 value in it, so your while() never terminates and you end up in a near-infinite loop and run off the end of the array.
The array is an array of numbers, not a string, so there is no reason whatsoever to think there there would be a null-terminator on the values. null terminators are for strings, not arrays of numbers.
In your function int sumOccur you have two problems-
1. sum and i are not initialized just declared. Initialize both to 0 .
2. Also while(A[i]!='\0') ain't going to work as expected as your array doesn't have that value in it.
Your code invokes undefined behaviour: you access A[6] and subsequent inexistent entries in sumOccur trying to find a final 0 in the array, but you do not put one in the definition of input in the main function.
-------- cut here if you are not interested in gory implementation details --------
The array is allocated on the stack, very near the top since it is instantiated in the main function. Reading beyond the end until you find a 0 likely tries to read beyond the end of the stack pages and causes a segmentation fault.
Note that you are dealing with an int array,which means it normally won't contain '\0' character.To iterate over the array you need to specify number of elements.Here is the correct way :
#include <stdio.h>
#include <stdlib.h>
int sumOccur(int A[],size_t number_of_elemets);
int main(){
int input[6] = {1,1,1,2,2,3};
//Get the number of elements
size_t n = sizeof(input) / sizeof(int);
printf("%d", sumOccur(input,n));
return 0;
}
int sumOccur(int A[],size_t number_of_elements) {
int sum = 0;
size_t i = 0;
while( i < number_of_elements )
{
sum += A[i];
i++;
}
return sum;
}
You are iterating while A[i] != '\0' but there is no '\0' in the array and also you never initialize sum which is unlikely the cause for a crash but it could be.
You need to pass the number of elements in the array, like this
#include <stdio.h>
#include <stdlib.h>
int sumOccur(size_t count, const int *A);
int sumOccurCHQrlieWay(const int *A, size_t count);
int main()
{
int input[] = {1, 1, 1, 2, 2, 3};
printf("%d", sumOccur(sizeof(input) / sizeof(*input), input));
return 0;
}
int sumOccur(size_t count, const int *A)
{
int sum;
sum = 0;
for (size_t i = 0 ; i < count ; ++i)
sum += A[i];
return sum;
}
int sumOccurCHQrlieWay(const int *A, size_t count)
{
return sumOccur(count, A);
}

Resources