I'm having problems by freeing the elements on my struct.
long code warning
typedef struct bingo
{
char board[5][5];
int* luckNum;
int* boardNum;
} bingo;
void update(bingo *pBingo,int num); //Function that gets a struct, number and checks if he is in the board, if it does he change it to "X"
int main(void)
{
srand(time(NULL));
int i, j, m, k, temp[75], *parr;
bingo player;
//For rellocating them later
if (!(player.luckNum = (int*) malloc(sizeof(int))))
{
printf("ERROR");
}
if (!(player.boardNum = (int*) malloc(sizeof(int))))
{
printf("ERROR");
}
//giving temp values of 1-75
for ( i = 0; i < 75; i++)
{
temp[i] = i + 1;
}
//Giving the player board random values of 1-75 without repeating the same number twice
for ( i = 0; i < 5; i++) //Passing on the rows
{
for (j = 0; j < 5; j++) //Passing on the columns
{
//
do
{
k = rand() % 75; //from 0-74
}
while (temp[k] == NULL); //while temp[k] is marked
player.board[i][j] = temp[k];
temp[k] = NULL; //NULL as a "flag" that marks the cell as taken (for not taking the same number twice)
player.luckNum=(int*) malloc(sizeof(int)*(i*j+j));
player.luckNum[i*j + j] = player.board[i][j];
}
}
//sets luckNum
for ( i = 0; i < 25; i++)
{
printf("%d ", player.luckNum[i]);
update(&player, player.luckNum[i]);
}
printf("\n");
for ( i = 0; i < 25; i++)
{
printf("%d",player.luckNum);
}
free(player.boardNum);
free(player.luckNum);
getchar();
return 0;
}
void update(bingo *pBingo, int num)
{
int i, j, k;
static int counter = 0,luckCounter = 25;
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
if (num == (int) (pBingo->board[i][j]))
{
pBingo->board[i][j] = 'X';
counter++;
pBingo->boardNum = (int*) realloc(pBingo->boardNum, sizeof(int)*counter);
pBingo->boardNum[counter] = num;
for (k = 0; k < luckCounter; k++)
{
if (pBingo->luckNum[k] == num)
{
num = pBingo->luckNum[k];
pBingo->luckNum[k] = pBingo->luckNum[luckCounter-1];
pBingo->luckNum[luckCounter-1] = num;
pBingo->luckNum = (int*) realloc(pBingo->luckNum, sizeof(int)*luckCounter);
luckCounter--;
}
}
}
}
}
}
Can anyone recognize what interrupts the free() function from freeing the memory?. I'm new to C and working on this code about good days so sorry for my ignorance about free() function, can anyone help me?
Ilan,
Don't be afraid to post your code with the necessary includes. First of all, are you heeding to the warnings of your compiler?
A few problem areas:
while (temp[k] == NULL)
You can research the difference between 0, NULL and '\0' but reserve the use of NULL for pointers. Also:
for ( i = 0; i < 25; i++)
{
printf("%d",player.luckNum);
}
Printf is expecting an integer and you're giving it a pointer. Finally, to address what I think is your problem, when you write "..interrupts the free() function from freeing the memory?" Do you mean your program simply not returning? If so then get rid of the final getchar(). You're still going to have at least one leak in this program. This address of this malloc:
if (!(player.luckNum = (int*) malloc(sizeof(int))))
will be lost as you assigned luck.Num a new address here without freeing the first:
player.luckNum=(int*) malloc(sizeof(int)*(i*j+j));
Related
My general goal with this question is to understand how to make use (say, print) of an array returned from an outer function. I'm using prime numbers as an example.
I'm new so going in-depth explaining... Sorry if there's un-needed info or misused terms :)
I defined a function "findprimes" to find every prime between 1 and x.
The function successfully prints an array of primes. However, I don't know if it returns the array of primes. And, if it does, I have no idea how to use said array in main().
This is the function 'findprimes':
int* findprimes(int x) {
int i, j, total=0;
int* numbers = (int*)malloc((x + 1) * sizeof(int));
/* initialization */
for (i = 0; i <= x + 1; i++) {
numbers[i] = 1;
}
/* find primes and assign prime=1 */
for (i = 2; i < sqrt(x); i++) {
if (numbers[i] == 1) {
for (j = i * i; j <= x; j = j + 2) {
if (j % i == 0) {
numbers[j] = 0;
}
}
}
}
/* count how many primes */
for (i = 1; i <= x; i++) {
if (numbers[i] == 1) {
total++;
}
}
/* put primes into their own array */
int* primes = (int*)malloc(total * sizeof(int));
for (i = 1,j=0; i <= x; i++) {
if (numbers[i] == 1) {
primes[j] = i;
j++;
}
}
//I want this part to be in main()
printf("The prime numbers between 1 and %d are: ", x);
for (i = 0; i < total; i++) {
printf("%d ", primes[i]);
}
return primes;
}
I want to print the 'primes' array in main, not in the function 'findprimes' itself. How can I do this?
int main() {
int n;
do {
printf("Enter a value for X>2: ");
scanf("%d", &n);
} while (n <= 2);
findprimes(n); //This returns 'primes' array
//I want to print 'primes' array here
}
Capture the return value in main():
int *primes = findprimes(n);
and use the array:
for (int i = 0; i < some_magic_number; i++)
{
printf("%d\n", primes[i]);
}
and remember to free the memory:
free(primes);
In fact, you also need to free numbers in the function.
The some_magic_number needs to be known — how does the main() function know how many elements are in the array? One way to fix that is to pass a pointer to the function that can hold the number of primes:
int *findprimes(int n, int *num_primes)
and use *num_primes = total; in the function before returning.
You could call the function with:
int some_magic_number;
int *primes = findprimes(n, &some_magic_number);
You'd probably choose an alternative name for the variable in main(), but it illustrates my point.
I am a bit of a beginner in C language. I was trying out a task of dynamically reallocating memory as the input comes through(although for this test I am doing a normal task, later will try to scale it up). the issue I am facing is I am unable to access the memory while writing into it. Can anyone please help me understand where I am going wrong in this code. thanks in advance.
code:
#include<stdio.h>
#include<stdlib.h>
struct ai {
int* a;
char* b;
};
int main()
{
struct ai *test;
test = (struct ai*) malloc(sizeof(struct ai));
test[0].a = (int*)malloc(sizeof(int));
test[0].b = (char*)malloc(sizeof(char));
/// storing info
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 4; j++)
{
test[i].a[j] = j;
test[i].b[j] = 65 + j;
test[i].a = (int *) realloc(test[i].a, (j + 2) * sizeof(int));
test[i].b = (char*) realloc(test[i].b, (j + 2) * sizeof(char));
}
test = (struct ai*)realloc(test, (i + 2) * sizeof(struct ai));
}
// printing the block out
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 4; j++)
{
printf("%d , %c\n", test[i].a[j], test[i].b[j]);
}
}
return 0;
} ```
You have missing initialization of your pointers and some other issues...
int main()
{
struct ai *test;
test = (struct ai*) malloc(sizeof(struct ai));
test[0].a = (int*)malloc(sizeof(int));
test[0].b = (char*)malloc(sizeof(char));
In C you should not cast the result of malloc. In best case it is useless. In worst case it hides real problems.
/// storing info
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 4; j++)
{
test[i].a[j] = j;
test[i].b[j] = 65 + j;
Here comes the reason for your segmentation fault:
You do not have any memory reserved for a and b except for the first element test[0]. All other array elements test[i] do not contain any useful data. Dereferencing these pointers is undefined behaviour.
You must allocate memory for each field after you enlarged your array.
test[i].a = (int *) realloc(test[i].a, (j + 2) * sizeof(int));
test[i].b = (char*) realloc(test[i].b, (j + 2) * sizeof(char));
You should never assign the return value of realloc to the same variable that you passed into the function. In case of an error you will get NULL return value and then your initiali pointer is lost.
Also here: don't cast for realloc as well.
}
test = (struct ai*)realloc(test, (i + 2) * sizeof(struct ai));
Same here: Don't assign to same variable and don't cast the result of realloc.
Finally: Here goes the missing part:
test[i+1].a = malloc(sizeof(*test[0].a));
test[i+1].b = malloc(sizeof(*test[0].b));
}
Of course you should check all return values for error results.
Not related to the segmentation fault, but still worth to fix:
You increment the size of each array after you used the last element.
This prepares the new element for being filled in next iteration of the loops. But in case of the last iteration it allocated an unused element for both the intern pointers a and b as well as the outer array test.
You will have some unused elements:
test[0].a[4]
test[0].b[4]
test[1].a[4]
test[1].b[4]
test[2].a[0]
test[2].b[0]
An improved solution could look like this (not tested)
I start with each pointer being NULL and use realloc right before the new element is used to avoid the extra elements.
int main(void)
{
struct ai *test = NULL
void *tmp;
// storing info
for (int i = 0; i < 2; i++)
{
tmp = realloc(test, (i+1) * sizeof(*test))
if (tmp == NULL)
exit(1);
test = tmp;
test[i].a = NULL;
test[i].b = NULL;
for (int j = 0; j < 4; j++)
{
tmp = realloc(test[i].a, (j+1) * sizeof(test[i].a[0]));
if (tmp == NULL)
exit(1);
test[i].a = tmp;
tmp = realloc(test[i].b, (j+1) * sizeof(test[i].b[0]));
if (tmp == NULL)
exit(1);
test[i].b = tmp;
test[i].a[j] = j;
test[i].b[j] = 65 + j;
}
}
// printing the block out
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 4; j++)
{
printf("%d , %c\n", test[i].a[j], test[i].b[j]);
}
}
return 0;
}
I am trying to read list of numbers from txt file and then sort them with Bucket sort.
so here is my code:
void bucketSort(int array[],int *n)
{
int i, j;
int count[*n];
for (i = 0; i < *n; i++)
count[i] = 0;
for (i = 0; i < *n; i++)
(count[array[i]])++;
for (i = 0, j = 0; i < *n; i++)
for(; count[i] > 0; (count[i])--)
array[j++] = i;
}
int main(int brArg,char *arg[])
{
FILE *ulaz;
ulaz = fopen(arg[1], "r");
int array[100];
int i=0,j,k,n;
while(fscanf(ulaz, "%d", &array[i])!=EOF)i++;
fclose(ulaz);
n=i;
for (j = 0; j<i; j++)
{
printf("Broj: %d\n", array[j]);
}
BucketSort(array,&n);
for (k = 0; k<i; k++)
printf("%d \n", array[i]);
return 0;
}
There are no errors in code,but when i call my function instead of sorted array i get array length random numbers(example: 2 3 5 4,after sorting i get 124520 124520 124520 124520 or some other random number) since i am a beginner,could someone help me with my code and what i did wrong? (sorry for bad english)
As Cool Guy correctly pointed out you have issues with memory access but on top of it the code does not sort anything. First you should read how Bucket Sort actually works.
In general:
You divide the input data among buckets by some criteria that guarantees that the buckets will not mess up the input order
Sort each bucket either using some other sorting method or recursively with bucket sort
Concatenate the sorted data (this is why the first point has the restriction of not messing up the input order)
Here is an example of your original code, I tried to adjust it as little as possible you it is easier for you to understand. This code divides a predefined input array among 3 buckets by range:
[-infinity][-1] -> first bucket
[0;10] -> second bucket
[11;infinity] -> third bucket
then performs Quicksort on each bucket and concatenates the result. I hope this helps to understand how this algorithm works.
#include <stdio.h>
#include <stdlib.h>
struct bucket
{
int count;
int* values;
};
int compareIntegers(const void* first, const void* second)
{
int a = *((int*)first), b = *((int*)second);
if (a == b)
{
return 0;
}
else if (a < b)
{
return -1;
}
else
{
return 1;
}
}
void bucketSort(int array[],int n)
{
struct bucket buckets[3];
int i, j, k;
for (i = 0; i < 3; i++)
{
buckets[i].count = 0;
buckets[i].values = (int*)malloc(sizeof(int) * n);
}
// Divide the unsorted elements among 3 buckets
// < 0 : first
// 0 - 10 : second
// > 10 : third
for (i = 0; i < n; i++)
{
if (array[i] < 0)
{
buckets[0].values[buckets[0].count++] = array[i];
}
else if (array[i] > 10)
{
buckets[2].values[buckets[2].count++] = array[i];
}
else
{
buckets[1].values[buckets[1].count++] = array[i];
}
}
for (k = 0, i = 0; i < 3; i++)
{
// Use Quicksort to sort each bucket individually
qsort(buckets[i].values, buckets[i].count, sizeof(int), &compareIntegers);
for (j = 0; j < buckets[i].count; j++)
{
array[k + j] = buckets[i].values[j];
}
k += buckets[i].count;
free(buckets[i].values);
}
}
int main(int brArg,char *arg[]) {
int array[100] = { -5, -9, 1000, 1, -10, 0, 2, 3, 5, 4, 1234, 7 };
int i = 12,j,k,n;
n=i;
for (j = 0; j<i; j++)
{
printf("Broj: %d\n", array[j]);
}
bucketSort(array, n);
for (k = 0; k<i; k++)
printf("%d \n", array[k]);
return 0;
}
Your code exhibits Undefined Behavior as you try to write into memory location which are not owned by your program.
for (i = 0; i < *n; i++)
(count[array[i]])++;
The above loop is causing the problem. You say that i is 4 which means that *n is also 4 and array contains 2 3 5 4. In the above code,count is an array of *n elements(in this case 4 elements) and the valid indices for the array are count[0],count[1],count[2] and count[3]. Doing
count[array[i]]
when i is zero is okay as it is same as count[2]. This is the same when i is 1 as it would be count[3] . After that ,when i is 4 and 5,count[4] and count[5] are wrong as you try to write to a invalid memory location.
Also,your code dosen't sort the values.
I am making a program in the C90 standard using GCC in Ubuntu 10.04, that randomly generates a hand of 5 card structs and calculates if the hand is a flush, straight, etc.
My function to calculate straights is:
int isStraight(card hand[]) {
int i, count = 1, result = 0;
for (i = 0; i < HAND_SIZE-1; i++) {
if (hand[i].pips == ((hand[i+1].pips) + 1)) {
count++;
}
}
if (count == HAND_SIZE)
result = 1;
return result;
}
My main function:
int main(void) {
int i, j;
int numHands = 0;
int flushCount = 0;
int straightCount = 0;
int xOfAKindCount = 0;
int straightFlushCount = 0;
int fullHouseCount = 0;
int isTwoPairCount = 0;
card deck[DECKSZ] = {0};
card hand[HAND_SIZE] = {0};
stack deckStack = {0};
stack handStack = {0};
initDeck(deck);
shuffleDeck(deck);
reset(&deckStack);
for (i = 0; i < DECKSZ; i++) {
push(deck[i], &deckStack);
}
do {
reset(&handStack);
for (i = 0; i < HAND_SIZE; i++) {
push(pop(&deckStack), &handStack);
if (isEmpty(&deckStack)) {
reset(&handStack);
shuffleDeck(deck);
reset(&deckStack);
for (j = 0; j < DECKSZ; j++) {
push(deck[j], &deckStack);
}
}
hand[i] = handStack.s[i];
}
numHands += 1;
arrangeHand(hand);
flushCount += isFlush(hand);
straightCount += isStraight(hand);
xOfAKindCount += isXOfAKind(hand, 2, 0);
straightFlushCount += isStraightFlush(hand);
fullHouseCount += isFullHouse(hand);
isTwoPairCount += isTwoPair(hand);
printf("Flushes:%d Straights:%d SF's:%d Number of Hands:%d\r",
flushCount, straightCount, straightFlushCount, numHands);
} while (1);
printf("\n");
return EXIT_SUCCESS;
}
My issue is my variable declared inside my function, result, is never set to 1 to indicate whether or not the hand is a straight, which therefore means my straightCount variable always remains at a value of zero. I do not have access to a debugger and in my mind the code I have makes sense. I'm new to programming in C, so if anybody could help me point out what is wrong with my function, I'd appreciate it. Thanks!
int isStraight(card hand[]) {
int step = 0;
for(int i = 1;i < HAND_SIZE; i++)
if(hand[i].pip != hand[i-1].pip+1)
/* Substitute step with i!=1 if over-edge invalid */
if(step || hand->pip != 1 || hand[i].pip != hand[i-1].pip+13-HAND_SIZE)
return 0;
else
step = 1;
return 1;
}
Right, after reading the code again, there are not enogh cards...
for (i = 0; i < HAND_SIZE-1; ++i)
Then you care counting pairs, not just individual cards, so
If (count == HAND_SIZE-1)
for (i = 0; i < HAND_SIZE-1; i++) { means that you are testing HAND_SIZE-1 pairs (which is correct), with i from from 0 to HAND_SIZE-2, so count will never be HAND_SIZE.
You just need to change your test to if (count == HAND_SIZE-1)
Assuming that (a) pip values are 1=Ace, 2=Deuce, ... and (b) the hand is sorted before being passed to the function, and (c) hands are exactly five cards, here's a quick one:
int isStraight(card hand[]) {
int i;
// Handle Broadway special case
if (hand[0].pips == 13 && hand[1].pips == 12 && hand[2].pips == 11 &&
hand[3].pips == 10 && hand[4].pips == 1) return 1;
// This will handle the rest
for (i = 0; i < (HAND_SIZE-1); i += 1) {
if (hand[i].pips != hand[i+1].pips) return 0;
}
return 1;
}
Also, I wouldn't use a structure for cards. Using a single integer is much faster and more versatile. Check out http://etceterology.com/blog/2013/5/23/representing-playing-cards-in-software
I' having a problem allocating a structure in a function. Here is the code(I'm currently using visual studio 2008):
Mat3x3* ProdMat(Mat3x3 *m, Mat3x3 *n)
{
if(m == NULL || n == NULL)
{
cout << "\t[W] Cannot compute product of the two matrixes one or both are NULL." << endl;
return NULL;
}
Mat3x3 *p; // product
int i, j;
float sum = 0;
p = (Mat3x3*)malloc(sizeof(Mat3x3)); // <= Exp cannot be evaluated
for(i = 0; i < 3; i++)
{
for(j = 0; j < 3; j++)
{
sum = 0;
for(int k = 0; k < 3; k++)
{
float a = m->a[i][k];
float b = n->a[k][j];
sum += a * b;
}
p->a[i][j] = sum;
}
}
return p;
}
P contains a matrix with 9 entries. Here is the context in which the error is given:
Mat3x3* compute_final_trans(Trans **transes) // compute product of all transformation matrixes from right to left
{
int k_trans = 0, i, j;
Mat3x3 *final_trans;
if(transes == NULL)
{
printf("\t[E] Cannot compute sequence of NULL transformations.\n");
return NULL;
}
final_trans = (Mat3x3*)malloc(sizeof(final_trans));
for(i = 0; i < 3; i++) // generate eye matrix
for(j = 0; j < 3; j++)
{
if(i == j)
{
final_trans->a[i][j] = 1;
}
else
{
final_trans->a[i][j] = 0;
}
}
while(transes[k_trans++]);
for(i = k_trans - 2; i >= 0; i--)
{
final_trans = ProdMat(transes[i]->matrix, final_trans); // <= ERROR
}
return final_trans;
}
Final trans is initialised as the eye matrix and transes have been succesfully computed before this step(before calling compute_final_trans). The while is used to retreieve the number of transformations that transes contains. At line:
final_trans = ProdMat(transes[i]->matrix, final_trans);
ProdMat fails to allocate memory for p which is a pointer to a Mat3x3 structure.
perror suggests that there isn't enough memory to allocate to the structure. However I'm only using 1GB of RAM(4GB in all).
Any help/suggestion/reference will be very much appreciated.
Sebi
malloc(sizeof(final_trans))
This is bad. You are only allocating enough space for a pointer, not space for an array.