Debugging a function in C - c

This function takes an integer array, the number of elements
in the array and tries to find a majority element in the
array. If the majority element exists, it is placed in
*result and the function returns true.
If no majority element exists, then the function returns
false. In that case, *result should not be used.
My output isn't working correctly for the program I'm writing and it is because of this findMajority function I think.
This is what the output is supposed to look like: http://pastebin.com/Q5ycXHrg
This is what my output looks like: http://pastebin.com/7P1ZTpML
This is the input:
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2
1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2
1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3
1 1 2 2 1 1 2 2 1 1 2 2 1 1 2 2 1 1 2 2 1 1 2 2 1 1 2 2 1 1
1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1
1 2 3
1 1 1
1 2 1
1 2
1 1
2
1 1 1 1 2 3 4 5 6 7
Here is the function:
int findMajority(int *array, int count, int *result){
int i, counter, bcount = 0, ccount = 0, candidate, j;
if(count == 1) {
*result = *array;
return true;
}
if(count % 2 != 0 ) {
for(i = 0; i < count; i++) {
if(*(array + i) == *(array + count)) {
counter++;
}
}
if(counter > (count/2)) {
*result = *(array + count);
return true;
}
else {
*(array + count) = 0;
count--;
}
}
for(j=0; j <= count; j += 2) {
if(*(array + j) == *(array + (j + 1))) {
*(array + (count + 1)) = *(array + j);
bcount++;//how many numbers on the end of the array
}
}
if(bcount == 1) {
int k = count;
while(*(array + k) == 0) {
candidate = *(array + k);
}
}
else
findMajority((array + count), count, result);
for(j=0; j <= count; j += 2) {
if(*(array + j) == candidate) {
ccount++;
}
}
if(ccount > (count/2)) {
*result = candidate;
return true;
}
else
return false;
}

Your function has a lot of problem.
Without intialising counter you are incrementing it
check whether array[count] is the valid last element or array[count-1] is the correct one
In this code for(j=0; j <= count; j += 2){
if(*(array + j) == *(array + (j + 1))){
*(array + (count + 1)) = *(array + j);
bcount++;//how many numbers on the end of the array
}}
for count= 3 you are accessing array[4] array[5] etc.
And this is a infinite loop. you are not modifying condition variable inside the loop while(*(array + k) == 0) { candidate = *(array + k); }

I suggest you learn how to use a debugger to debug your program. For example, after wrapping your code with the following:
#include <stdio.h>
typedef enum { false, true } boolean;
// ((( your function here )))
int main(int argc, char* argv[])
{
int result = 0;
int number = 0;
int test[] = { 1, 1, 1, 1, 1, 1, 1 };
result = findMajority(&test[0], sizeof(test) / sizeof(int), &number);
printf("Result = %d, Number = %d\n", result, number);
return 0;
}
Assuming you put this into 'question.c' you could then issue the commands (assuming you have gcc and gdb):
$ gcc -g -o question question.c
$ gdb ./question
(gdb) b findMajority
Breakpoint 1 at 0x80483ea: file question.c, line 6.
(gdb) run
Starting program: ./question
Breakpoint 1, findMajority (array=0xbffff4bc, count=7, result=0xbffff4d8) at question.c:6
6 int i, counter, bcount = 0, ccount = 0, candidate, j;
You can then use the n command to step to the next line, and the p command to print variables to see what's going wrong. For example, you could find some of the problems that Toms pointer out relatively quickly:
39 while(*(array + k) == 0){
(gdb) n
40 candidate = *(array + k);
(gdb) n
39 while(*(array + k) == 0){
(gdb) n
40 candidate = *(array + k);
(gdb) n
39 while(*(array + k) == 0){
(gdb) n
There's your infinite loop.
(gdb) p counter
$3 = -1207959944
And there's your uninitialized counter.
Part of learning programming is figuring out strategies of determining just what went wrong. Some people like to use text-based debuggers like gdb. Some people like graphical debuggers like you could find in Eclipse CDT. Some people put printf() statements throughout their code.
Once you're really good, like Toms, you can just read it and rattle off the problems. ;-)

Related

I don't understand my mystake trying to initialise and fill a dynamic 2D array using data in a file

first post here. I am trying, through a function to initialise a 2D array. Before I use the function, I don't know the array dimensions so I think I have to use malloc. Moreoever the data I try to read is positionned in a .txt file so I use the fscanf function. Here is the code which is surely more understandable.
typedef struct Level Level;
struct Level{
int height;
int width;
int **matrix;
};
int main(){
Level test;
Level *testPtr=&test;
getLvl(testPtr);
int i,j;
printf("height=%d,width=%d",test.height,test.width); //veryfing I get the right height and width
for(i=0;i<test.height;i++){
for(j=0;j<test.width;j++){
printf("test[%d][%d]=%d\n",i,j,test.matrix[i][j]);//printing the value supposed to be there
}
}
}
void getLvl(Level *testPtr){
FILE *doc=NULL;
doc=fopen("doc.txt","r"); //open my file
fscanf(doc,"%d",&testPtr->height); //get the height and width
fscanf(doc,"%d",&testPtr->width);
test->matrix=malloc(sizeof(int*)*testPtr->height*testPtr->width); //initialise the matrix as an array of pointer
int i,j;
for(i=0;i<testPtr->height;i++){
test->matrix[i]=malloc(sizeof(int)*testPtr->width); //allocate every elements of the array enough memory to store the data of every
for(j=0;j<test->width;j++){
fscanf(doc,"%d",matrix[i][j]);
}
}
}
So when I try to execute my code I have no issue getting the height and width. However getting the values of the array make the console crashes. From what I know this comes from an issue trying to reach memory I don't have access to.
My doc file looks something like this :
10
10
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
EDIT :
Here is the original code (in French) :
typedef struct Niveau Niveau;
struct Niveau{
int hauteur;
int largeur;
int **cases;
int positionX;
int positionY;
};
void getLvl(Niveau *test);
int main()
{
Niveau test;
Niveau *testPTR=&test;
getLvl(testPTR);
printf("hauteur vaut %d\n",test.hauteur);
printf("largeur vaut %d\n",test.largeur);
int i,j;
for(i=0;i<10;i++){
for(j=0;j<10;j++){
printf("Valeur de tableau[%d][%d] vaut %d\n",i,j,test.cases[i][j]);
}
}
}
void getLvl(Niveau *test){
char verif;
FILE* doc=NULL;
doc=fopen("doc.txt","r");
fscanf(doc,"%c",&verif);
int i,j;
if(verif=='A'){
fscanf(doc,"%d",&test->hauteur);
fscanf(doc,"%d",&test->largeur);
}
fscanf(doc,"%c",&verif);
if(verif=='B'){
test->cases=malloc(sizeof(int*)*test->hauteur*test->largeur);
for (i=0;i<test->hauteur;i++){
test->cases[i]=malloc(sizeof(int)*test->largeur);
for(j=0;j<test->largeur;j++){
fscanf(doc,"%d",test->cases[i][j]);
}
}
}
}
The main the txt file is exactly :
A
10
10
B
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
C
here add one space fscanf(doc, " %c", &verif); in this fscanf before %c,otherwise you will take \n as input.
and here fscanf(doc, "%d", test->cases[i][j]); add & to your fscanf like this fscanf(doc, "%d", &test->cases[i][j]);

Print a console "picture" using recursion

I'm having some trouble printing the following picture.
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 (16 times)
2 2 2 2 2 2 2 2 2 2 2 2 (12 times)
3 3 3 3 3 3 3 3 (8 times)
4 4 4 4 (4 times)
3 3 3 3 3 3 3 3 (8 times)
2 2 2 2 2 2 2 2 2 2 2 2 (12 times)
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 (16 times)
It's easy for me to implement an iterative algorithm, but I have to use recursion. I've written the following code (C++) that seems to do the job.
void print(int n, int current)
{
int offset = (n / 2) * (current - 1);
int i;
for (i = 0; i < offset; i++)
printf(" ");
for (i = 1; i <= (n - current + 1) * n; i++)
printf("%i ", current);
printf("\n");
}
void picture(int n, int current)
{
if (current < n) {
print(n, current);
picture(n, current + 1);
print(n, current);
}
else
if (current == n)
print(n, current);
}
int main()
{
int n;
input: printf("Enter n --> ");
scanf_s("%i", &n);
if ((n < 1) || (n > 9) || (n % 2 == 1)) {
printf("ERROR: n must be an even decimal digit!\n");
goto input;
}
picture(n, 1);
return 0;
}
I wonder whether there is a simpler way to write the recursive function here.
Update: I've tried to identify the recursion in a much simpler problem of printing the "pyramid":
1
2 2
3 3 3
4 4 4 4
5 5 5 5 5
The function pyram receives two parameters: the maximum number n (5 in our case) and the current number k. k is printed k times, then pyram is called with the parameters n and k + 1. This happens only when k <= n.
void pyram(int n, int k)
{
if (k <= n) {
for (int i = 1; i <= k; i++)
printf("%i ", k);
printf("\n");
pyram(n, k + 1);
}
}
I've written my solution to the original problem in a similar manner.
You can use static variables in the recursive function. In this case the function declaration will look simpler and you will not need an auxiliary function.
For example
#include <stdio.h>
void display_pattern( unsigned int n )
{
const unsigned int FACTOR = 4;
static unsigned int value = 1;
static int indent = 1;
if ( n )
{
printf( "%*u", indent, value );
for ( unsigned int i = 1; i < FACTOR * n; i++ ) printf( " %u", value );
putchar( '\n' );
indent += FACTOR;
++value;
display_pattern( --n );
indent -= FACTOR;
--value;
}
if ( n++ )
{
printf( "%*u", indent, value );
for ( unsigned int i = 1; i < FACTOR * n; i++ ) printf( " %u", value );
putchar( '\n' );
}
}
int main(void)
{
const unsigned int N = 10;
while ( 1 )
{
printf( "Enter a non-negative number less than %u (0 - exit): ", N );
unsigned int n;
if ( scanf( "%u", &n ) != 1 || n == 0 ) break;
if ( !( n < N ) ) n = N - 1;
putchar( '\n' );
display_pattern( n );
putchar( '\n' );
}
return 0;
}
The program output can look like
Enter a non-negative number less than 10 (0 - exit): 10
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
7 7 7 7 7 7 7 7 7 7 7 7
8 8 8 8 8 8 8 8
9 9 9 9
8 8 8 8 8 8 8 8
7 7 7 7 7 7 7 7 7 7 7 7
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Enter a non-negative number less than 10 (0 - exit): 4
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3
4 4 4 4
3 3 3 3 3 3 3 3
2 2 2 2 2 2 2 2 2 2 2 2
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
Enter a non-negative number less than 10 (0 - exit): 0
As for the function pyram then it can look like
void display_triangle( unsigned int n )
{
if ( n )
{
display_triangle( n - 1 );
for ( unsigned int i = 0; i < n; i++ ) printf( "%u ", n );
putchar( '\n' );
}
}

Algorithm to fill 2D array in C

and sorry for the noob question.
So I've been asked to create an algorithm to fill a 2D array. They didn't say what the rules were, however, I've been told that the resulting matrix should look like this:
1 1 1 1 1
1 2 2 2 1
1 2 3 2 1
1 2 2 2 1
1 1 1 1 1
I haven't been told if the matrix is necessarily square, but the size may vary.
So substantially what I'm seeing is the matrix is vertically, horizontally and diagonally symmetrical.
Now whatever I try, it ends up being super complicated, while as I look at it, I feel like it should be pretty simple...
Any trick or snippet on how you'd do it?
Thanks in advance.
You need 2 nested loops, to traverse through rows and columns. The content of the field is the minimum of the control variables and and the minimum of the difference of a control variable and the size of the array dimension, incremented by 1.
N = 5
0: min(0, N-0-1) + 1 = 1
1: min(1, N-1-1) + 1 = 2
2: min(2, N-2-1) + 1 = 3
3: min(3, N-3-1) + 1 = 2
4: min(4, N-4-1) + 1 = 1
#include <stdio.h>
#define N 5
#define MIN(a,b) (((a)<(b))?(a):(b))
int main()
{
int a[N][N];
for ( int i = 0; i < N; ++ i )
{
for ( int j = 0; j < N; ++ j)
{
int minI = MIN(i, N-i-1);
int minJ = MIN(j, N-j-1);
a[i][j] = MIN(minI, minJ) + 1;
printf("%d ", a[i][j]);
}
printf("\n");
}
return 0;
}
Output:
1 1 1 1 1
1 2 2 2 1
1 2 3 2 1
1 2 2 2 1
1 1 1 1 1
See the live example

generate all possible combinations of array values in C

I have an array of N values from 0 to k (0 <= k <= N), I need to generate all possible combinations of N values
void generate(int n, int k) {
int q = -1;
char res = '|';
int r;
int j;
for (j = 1; j <= n; j++) {
q = j / (k + 1);
r = j % (k + 1);
printf("%d %c", r, res);
}
}
int main() {
int n = 2;
int k = 2;
int i, nbr_comb;
nbr_comb = pow((k + 1), n); number of combinations
for (i = 0; i < nbr_comb; i++) {
generate(n, i);
printf("\n");
}
return (EXIT_SUCCESS);
}
for this test (N=2 K=2) I had those combinations
0 |0 |
1 |0 |
1 |2 |
1 |2 |
1 |2 |
1 |2 |
1 |2 |
1 |2 |
1 |2 |
you see that it begins to generate but it fixed at a point, I can't find why ! ?
Expected Examples:
for n=2 k=2 n=3 k=2
0 0 0 0 0
0 1 0 0 1
0 2 0 0 2
1 0 1 0 0
1 1 1 0 1
1 2 1 0 2
2 0 1 1 0
2 1 1 1 1
2 2 1 1 2
1 2 0
1 2 1
1 2 2
2 0 0
.....
This is how your loops unfurl at n=2, k=2:
for (i=0; i<nbr_comb; i++)
i=0: generate(2,0) --> j=1: 1 mod 1 = 0
j=2: 2 mod 1 = 0
i=1: generate(2,1) --> j=1: 1 mod 2 = 1
j=2: 2 mod 2 = 0
i=2: generate(2,2) --> j=1: 1 mod 3 = 1
j=2: 2 mod 3 = 2
i=3: generate(2,3) --> j=1: 1 mod 4 = 1
j=2: 2 mod 4 = 2
i=4: generate(2,4) --> j=1: 1 mod 5 = 1
j=2: 2 mod 5 = 2
i=5: generate(2,5) --> j=1: 1 mod 6 = 1
j=2: 2 mod 6 = 2
i=6: generate(2,6) --> j=1: 1 mod 7 = 1
j=2: 2 mod 7 = 2
i=7: generate(2,7) --> j=1: 1 mod 8 = 1
j=2: 2 mod 8 = 2
i=8: generate(2,8) --> j=1: 1 mod 9 = 1
j=2: 2 mod 9 = 2
As you can see, your j for-loop in generate() just keeps calling modulo on j, the result of which will always be j once argument k is greater than j.
What you need is a nested for-loop that will take the current combination (range [0..(k+1)^n]) and the current array index (range [0..n-1]) into consideration when it decides which value to print from the set of [0..k].
If you think of the output as rows and columns, then in the right-most column, the value should change on each row, iterating from 0..k. In next column, the value should change every (k+1)th row. In next column, the value should change every (k+1)^2 row.
For example, when n = 3 and k = 2, then for the first 9 rows, the right-most column should look like 0,1,2,0,1,2,0,1,2. The middle column should look like 0,0,0,1,1,1,2,2,2. The left-most column should look like 0,0,0,0,0,0,0,0,0.
Thus, you end up with something like this:
int n = 2;
int k = 2;
int row, col;
int cell;
int rdiv;
int nbr_comb = pow(k+1, n);
for (row=0; row < nbr_comb; row++)
{
for (col=n-1; col>=0; col--)
{
rdiv = pow(k+1, col);
cell = (row/rdiv) % (k+1);
printf("%d |", cell);
}
printf("\n");
}

printing a periodical series of a number in C

Given a Periodical Series of numbers
Example X=3
the Periodical Series of x=3 must look like this
1 1 1
1 1 2
1 1 3
1 2 1
1 2 2
1 2 3
1 3 1
1 3 2
1 3 3
2 1 1
2 1 2
2 1 3
2 2 1
2 2 2
2 2 3
2 3 1
2 3 2
2 3 3
3 1 1
3 1 2
3 1 3
3 2 1
3 2 2
3 2 3
3 3 1
3 3 2
3 3 3
Wanted: to write a program in C to print this series
and given : Assume maximum value of x can be 10
I tried to start with ideas.. but all failed..
Please HELP . thanks :)
def yourFunction(n, x):
recursiveFunction(n, x, 0, [0]*n)
def recursiveFunction(depth, breadth, currentDepth, indexes):
if currentDepth >= depth:
print indexes
else:
for indexes[currentDepth] in range(0, breadth):
recursiveFunction(depth, breadth, currentDepth + 1, indexes)
#include<stdio.h>
#include<stdlib.h>
int printSeries(int list[], int max, int level){
if(level == max){
int i;
for(i=0;i<max;++i)
printf("%d ", list[i]);
printf("\n");
return 1;
}
while(list[level]<=max){
list[level]+=printSeries(list, max, level+1);
}
list[level] = 1;
return 1;
}
void printSeriesStart(int x){
int i, *list = malloc(x*sizeof(int));
for(i=0;i<x;++i){
list[i]=1;
}
printSeries(list, x, 0);
free(list);
}
int main(void){
int X = 3;
printSeriesStart(X);
return 0;
}

Resources