I was building a simple program to count the frequencies of the numbers in a dice experiment, but I tried to expand it and increase the maximum amount of throws to huge numbers, and by trial and error I found the max limit to be 519253.
With this maximum value I can’t create any new arrays either, it crashes.
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MX 519253
#define DICE 6
void throwdice(int n[], int size);
int genNum();
void printv(int n[], int size);
void countd(int n[], int size, int count[DICE]);
int main ()
{
srand(time(NULL));
int throws[MX];
int count[DICE]={0};
int n;
//printf("Number of dice to throw: ");
//scanf("%d",&n);
n=MX;
throwdice(throws,n);
//printf("Throw\tNumber");
//printv(throws,n);
countd(throws,n,count);
printf("\n\nNumber\tFrequency");
printv(count,DICE);
}
int genNum()
{
int n;
n=rand()%DICE+1;
return n;
}
void printv(int n[], int size)
{
int i;
for (i = 0; i < size; i++)
printf("\n%d \t%d",i+1,n[i]);
}
void throwdice(int n[], int size)
{
int i;
for (i = 0; i < size; i++)
n[i]=genNum();
}
void countd(int n[], int size, int count[DICE])
{
int i;
for (i = 0; i < size; i++)
count[n[i]-1]++;
}
Is there a way to expand this program to account for, say a million throws?
Try changing this;
int throws[MX];
to either this, or move it to a global scope;
static int throws[MX];
I think you're probably overflowing the stack.
You can try to put the array on the heap like this;
int *throws = malloc(sizeof(int)*MX);
Related
My function does not work and I do not know why, it ends after entering the range. Could you explain why and how to fix it? I need to do this using these pointers to the array.
void generate(int *pa, int *pa2);
void display(int *pa, int *pa2);
int main()
{
srand(time(0));
int size;
printf("Enter size of array\n");
scanf("%d",&size);
int *A=(int*) malloc(size*sizeof(int));
int *ptr=A;
int *pa=&ptr[0];
int *pa2=&ptr[size-1];
generate(pa,pa2);
display(pa,pa2);
return 0;
}
void generate(int *pa, int *pa2)
{
int upper,lower;
int randi;
printf("enter range");
scanf("%d %d",&lower,&upper);
for (int i = 0; i <*pa2; i++)
{
randi=(rand() % (upper - lower + 1)) + lower;
*(pa+i) = randi;
}
}
for (int i = 0; i <*pa2; i++)
You've mixed up iterating by index with iterating until you hit a pointer. That's comparing the value of the end of the array, which is garbage, to i.
Instead you need to compare the pointers pa+1 to pa2. And it has to be <= because you do want to fill in the last item.
for (int i = 0; (pa+i) <= pa2; i++) {
*(pa+i) = ...
}
But it's easier to get rid of i and increment a pointer directly.
void generate(int *start, int *end) {
...
for(int *current = start; current <= end; current++) {
*current = ...;
}
}
But since you have the size, it's simpler to pass in the size and iterate by index.
void generate(int *array, int size) {
...
for (int i = 0; i <= size; i++) {
array[i] = ...
}
}
And you can simplify calling the function. A and &A[0] point to the same memory.
generate(A, &A[size-1]);
If this has any error, kindly mention it. Because I may figure out some future consequences
#include<stdio.h>
int main()
{
int a[]={1,2,3,4,5,5,4,3,4,5},count[10]={0},i;
for(i=0;i<sizeof(a)/sizeof(a[0]);i++)
{
int x;
x=a[i];
count[x]=count[x]+1;
}
for(i=0;i<sizeof(count)/sizeof(count[0]);i++)
{
if(count[i]!=0)
{
printf("\n %d:%d",i,count[i]);
}
}
}
Generally? No. In this specific case? Maybe.
Instead of sizeof(a)/sizeof(a[0]), use a macro to get the array size.
Dont declare/initialize a loop variable and two arrays in one line.
You will get out of bounds issues as soon as a contains a number that is bigger than the length of count - 1 or smaller than 0.
I would do something like the following:
#include <stdio.h>
#include <string.h>
#define ARRAY_COUNT(array) (sizeof(array)/sizeof(array[0]))
void GetCountOfNumberInArray(int intArray[],
unsigned int intArraySize,
int numbersToCount[],
unsigned int numberCount[],
unsigned int numbersToCountSize){
memset(numberCount, 0, numbersToCountSize * sizeof(numbersToCountSize));
unsigned int count = 0;
for(unsigned int i = 0; i < intArraySize; i++){
for(int j = 0; j < numbersToCountSize; j++){
if(numbersToCount[j] == intArray[i]){
numberCount[j]++;
break;
}
}
}
}
int main(int argc, char *argv[]){
int intArray[] = {1,2,3,4,5,5,4,3,2,1};
int numbersToCount[] = {1,2,3,4,5,6,7,8,9,10};
unsigned int numberCount[ARRAY_COUNT(numbersToCount)];
GetCountOfNumberInArray(intArray,
ARRAY_COUNT(intArray),
numbersToCount,
numberCount,
ARRAY_COUNT(numbersToCount));
for(unsigned int i = 0; i < ARRAY_COUNT(numbersToCount); i++){
printf("number %i appears %u times in the array\n", numbersToCount[i], numberCount[i]);
}
}
That way you get a universal function to count a set of numbers in an array that still works similar to your original solution.
My issue is that I am getting segmentation fault (core dumped) each time I try, I have yet to clean up my code, but I am stumped.
I must enter the values in with the compiler e.g "./filename 0 100" whereby 0 is min and 100 is max.
It must then fill the array of 10 elements with random numbers (0-100). I am so close, just can't fathom the main function.
Also, how can I print the array {0,1,2,3} in format "[0,1,2,3]" including the commas, without it looking like "[0,1,2,3, ]"
#include <stdlib.h>
#include <stdio.h>
int getRandom(int min, int max);
void fillArray(int data[], int size, int min, int max);
void printArray(int data[], int size);
int main(int argc, char *argv[]) {
int a;
int b;
if (argc>=3){
a = atoi(argv[1]);
b = atoi(argv[2]);
int arr[10];
printf("\t An array with random values from 0 to 100 \n");
fillArray(arr,10 ,a, b);
printArray(arr, 10);
} else {
printf("Incorrect number of arguments - please call with assignment min max\n");
}
return 0;
}
int getRandom(int min, int max) {
int result = 0;
int low = 0;
int high = 0;
if (min<max) {
low = min;
high = max+1;
} else {
low = max + 1;
high = min;
}
result = (rand() % (high-low)) + low;
return result;
}
void fillArray(int data[], int size, int min, int max){
int i;
for(i=min ; i < max+1; i++){
data[i] = getRandom(min,max);
}
}
void printArray(int data[], int size){
int i;
printf("[");
for(i=0; i<size; i++){
printf("%d,", data[i]);
}
printf("]");
}
I agree with #Steve Friedl that the main problem with your program lies in the fillArray function. There i should run from 0 to size.
As for your second question, testing whether you're printing the last number helps to suppress the unwanted comma:
void printArray(int data[], int size) {
printf("[");
for (int i = 0; i < size; i++) {
printf("%d", data[i]);
if (i < size - 1)
printf(",");
}
printf("]");
}
If you prefer a more compact solution (although with an optimizing compiler there's not really a difference), you could write it as:
void printArray(int data[], int size) {
printf("[");
for (int i = 0; i < size; i++) {
printf("%d%c", data[i], i < size-1 ? ',' : ']');
}
}
Also, in your main function, you should include a and b in your printing:
printf("\t An array with random values from %d to %d \n", a, b);
I believe this is blowing things up for you:
void fillArray(int data[], int size, int min, int max){
int i;
for(i=min ; i < max+1; i++){ // <-- HERE
data[i] = getRandom(min,max);
}
}
The calling function allocates 10 items in the arr array, and that's passed as the size parameter, but you're not using that parameter to limit filling up the array. If the max value is 100, then it's trying to fill one hundred slots instead of just ten.
for (i = 0; i < size; i++)
data[i] = getRandom(min,max);
should fix at least this issue.
EDIT: The comma thing, I prefer to add commas before the items unless this is the first. In this case it doesn't matter much, but it's more general, especially for variable-length lists where you don't know you're at the end until you get there. Augmenting the helpful response from #JohanC :
void printArray(int data[], int size) {
printf("[");
for (int i = 0; i < size; i++) {
if (i > 0) printf(",");
printf("%d", data[i]);
}
printf("]");
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Program compiles fine, but returns 'segmentation fault' when ran. Please help. thanks. Ignore the other three functions. The program should Fill an array and the print the value in the array, using pointers and pointer arithmetic
#include <stdio.h>
void FillArray ( int *array, int size );
void PrintArray ( int *array, int size );
//void BubbleSort ( int *array, int size );
//void SelectionSort ( int *array, int size );
//void Swap ( int *x, int *y );
#define SIZE 20
int main (void)
{
int NumList [SIZE];
FillArray(NumList, SIZE);
PrintArray (NumList, SIZE);
}
void PrintArray (int *array, int size)
{
int i;
for (i=0; i<100; i++)
{
printf("%d \t", *(array+i));
}
}
void FillArray(int *array, int size)
{
int i;
srand(time(NULL));
for (i=0; i<100; i++)
{
*(array+i)= rand()%101;
}
return;
}
Your array contain only 20 entries but you tried to access invalid entries whose indexes were from 20 to 99.
You are trying accesing out-of-bound elements. Here is a quick fix:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 100
void FillArray ( int *array, int size );
void PrintArray ( int *array, int size );
int main (void)
{
int NumList [SIZE];
FillArray(NumList, SIZE);
PrintArray (NumList, SIZE);
}
void PrintArray (int *array, int size)
{
int i;
for (i=0; i<100; i++)
{
printf("%d \t", array[i]);
}
}
void FillArray(int *array, int size)
{
int i;
srand(time(NULL));
for (i=0; i<100; i++)
{
array[i] = rand() % 101;
}
}
You are trying to access out-of-bound elements. Here is the right way to do it.
Although you pass size of array as another argument, instead of using it, you're using a larger size of 100 which is hard coded.
#include <stdio.h>
void FillArray ( int *array, int size );
void PrintArray ( int *array, int size );
#define SIZE 20
int main (void)
{
int NumList [SIZE];
FillArray(NumList, SIZE);
PrintArray (NumList, SIZE);
}
void PrintArray (int *array, int size)
{
int i;
for (i=0; i < size; i++)
{
printf("%d \t", *(array+i));
}
}
void FillArray(int *array, int size)
{
int i;
srand(time(NULL));
for (i=0; i < size; i++)
{
*(array+i)= rand()%101;
}
return;
}
I'm trying to write a program that dynamically allocates memory for an array, which the user then fills with integer values and the program sorts said integer values. However, it seems that my array isn't working as intended. I have managed to get the program working with a static array, but the dynamic allocation is causing me a lot of problems with incorrect values and whatnot. Here's what I have so far for the dynamically allocated version (if it would help you guys, I can also provide the version that uses a static array):
#include <stdio.h>
#include "genlib.h"
#include "simpio.h"
void sortArray (int *numbers, int i2);
int indexMax (int *numbers, int low, int high);
void swap (int *num1, int *num2);
int getArray (int *numbers);
void displayArray (int *numbers, int i2);
main()
{
int *numbers, i2;
i2=getArray(numbers);
sortArray(numbers, i2);
displayArray (numbers, i2);
}
int getArray (int *numbers)
{
int i, i2;
printf("Please enter the amount of elements you wish to sort: ");
i2=GetInteger();
numbers=(int *)malloc(i2*sizeof(int));
for(i=0;i<i2;i++, numbers++)
{
printf("Enter next integer: ");
*numbers=GetInteger();
printf("\n");
}
return(i2);
}
void displayArray (int *numbers, int i2)
{
int i;
printf ("\nThe sorted list is: \n\n");
for (i=0;i<i2;i++, numbers++)printf ("%d\n", *numbers);
}
void sortArray (int *numbers, int i2)
{
int i, minInd;
for(i=0;i<i2;i++)
{
minInd=indexMax(numbers, i, i2-1);
swap(&numbers[i], &numbers[minInd]);
}
}
int indexMax (int *numbers, int low, int high)
{
int i, maxInd;
maxInd=high;
for (i=high;i>=low;i--)
{
if(*(numbers+i)>*(numbers+maxInd)) maxInd=i;
}
return (maxInd);
}
void swap (int *num1, int *num2)
{
int temp;
temp=*num1;
*num1=*num2;
*num2=temp;
}
Here is a working solution:
#include <stdio.h>
#include <stdlib.h>
void sortArray (int *numbers, int i2);
int indexMax (int *numbers, int low, int high);
void swap (int *num1, int *num2);
int getArray (int **numbers);
void displayArray (int *numbers, int i2);
main()
{
int *numbers, i2;
i2=getArray(&numbers);
sortArray(numbers, i2);
displayArray (numbers, i2);
}
int getArray (int **numbers)
{
int i, i2;
printf("Please enter the amount of elements you wish to sort: ");
scanf("%d", &i2);
(*numbers) = malloc(i2 * sizeof(int));
int *temp = *numbers;
for(i = 0; i < i2; i++)
{
printf("Enter next integer: ");
scanf("%d", &temp[i]);
printf("\n");
}
return(i2);
}
void displayArray (int *numbers, int i2)
{
int i;
printf ("\nThe sorted list is: \n\n");
for (i=0;i<i2;i++, numbers++)printf ("%d\n", *numbers);
}
void sortArray (int *numbers, int i2)
{
int i, minInd;
for(i=0;i<i2;i++)
{
minInd=indexMax(numbers, i, i2-1);
swap(&numbers[i], &numbers[minInd]);
}
}
int indexMax (int *numbers, int low, int high)
{
int i, maxInd;
maxInd=high;
for (i=high;i>=low;i--)
{
if(*(numbers+i)>*(numbers+maxInd)) maxInd=i;
}
return (maxInd);
}
void swap (int *num1, int *num2)
{
int temp;
temp=*num1;
*num1=*num2;
*num2=temp;
}
The thing is in your main when you are declaring int *numbers , numbers pointer is pointing to some junk memory location as local variables can have any garbage value, so while you are passing this numbers pointer to getArray() function you are passing its value, Suppose numbers is pointing to some random value = 1234 and suppose address of numbers is = 9999. Now when you call getArray(numbers) you tell taht whatever is there in numbers pass it to getArray's numbers variable that we are letting is 1234.
Then when you allocate memory to numbers that is local variable of getArray() function not main's and it might have address suppose = 0x8888. Then malloc allocates some address space as specified and stores the start address of that allocated address space(suppose i.e. = 0x7777) into location 0x8888 not 0x9999 which is the adress of main's numbers variable.
Thus when the getArray function ends and next time you call sortArray you pass it value present in numbers variable of main which is still junk 1234. and the actual value you should be passing is present at address 0x8888.
Try this:
int main(void)
{
int *numbers, i2;
i2 = getArray(&numbers);
sortArray(numbers, i2);
displayArray (numbers, i2);
return 0;
}
int getArray (int **numbers)
{
int i, i2;
printf("Please enter the amount of elements you wish to sort: ");
i2 = GetInteger();
*numbers = malloc(i2 * sizeof int);
etc...
You simply need one more level of indirection to make int getArray(int**) return a pointer to an allocated array.
As an aside, you can use the C library function qsort() to do the sorting work for you. Here is an example:
int main(void)
{
int a[]={4,7,9,1,34,90,66,12};
qsort(a, sizeof(a)/sizeof(a[0]), sizeof(int), compare);
return 0;
}
int compare(const void *a, const void *b){
const int *x = a, *y = b;
if(*x > *y)
return 1;
else
return(*x < *y) ? -1: 0;
}
Works just as well with dynamically allocated int arrays, or char arrays