0

I past all my day to fix Code Blocks, I had a lot of troubles with it. Seems to be fixed, I decide to code and i'm trying to display a tray ( two dimensional arrays ) as a parameter of a function. I follow an answer on this website to make it right. But now, i have an error when I compile. Here's my files.

main.c

#include <stdio.h>
#include <stdlib.h>
#include "SudokuH.h"

int main(void)
{
    int tray[9][9]={};
    displayTray(numRows, numCols, tray);
    return 0;
}

SudokuH.h

#ifndef SUDOKUH_H_INCLUDED
#define SUDOKUH_H_INCLUDED

int numRows = 9;
int numCols = 9;
int i,j;

void displayTray (int numRows, int numCols, int pt[][numCols]);

#endif // SUDOKUH_H_INCLUDED

SudokuS.c

#include <stdio.h>
#include <stdlib.h>
#include "SudokuH.h"

void displayTray(int numRows, int numCols, int pt[][numCols]){
    printf("A|B|C|D|E|F|G|H|I\n");
    for (i=0; i<numRows;i++){
            printf("%d|",i);
            for (j=0; j<numCols;j++){
                printf("%i|",pt[i][j]);
            }
    }
}

At the beginning, I thought this error came from CodeBlocks but i try to make again without creating a project and it didn't work. And my others programs seem to work. So what's wrong with my code ? I checked my parameter but it seems ok so maybe it's my way to use a two dimensional array as parameter ? The error is :

||=== Build: Debug in Sudoku (compiler: GNU GCC Compiler) ===| ||error: ld returned 1 exit status| ||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

I have this in the build log :

obj\Debug\main.o:main.c:(.data+0x0): first defined here obj\Debug\SudokuS.o:SudokuS.c:(.data+0x4): multiple definition of `numCols' obj\Debug\main.o:main.c:(.data+0x4): first defined here collect2.exe: error: ld returned 1 exit status

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
KIToRe
  • 39
  • 8
  • 1
    It's a linker error. You're missing a file somewhere... – Shark Mar 28 '16 at 15:07
  • How can I fix this ? Why is it appearing only with this project and these files and not other one ? – KIToRe Mar 28 '16 at 15:16
  • @Shark: "*missing a file*"? "*multiple definition of `numCols'*"! – alk Mar 28 '16 at 15:18
  • @alk he added that info later, `"multiple definition of 'numCols'"` is a giveaway. – Shark Mar 29 '16 at 07:43
  • this line: `int tray[9][9]={};` does not initialize the `tray[][]` array. To initialize the array use something similar to: `int tray[9][9]={{ 0 }}; – user3629249 Mar 29 '16 at 16:13
  • the posted code contains several 'magic' numbers. 'magic' numbers make the code much more difficult to understand, debug, maintain. I.E. 9. Suggest using #define statements to give the 'magic' numbers meaningful names, then use those meaningful names throughout the code. – user3629249 Mar 29 '16 at 16:15
  • do not define variable instances (int i,j;) in a header file. – user3629249 Mar 29 '16 at 16:18
  • When indenting the code, do not use tabs because every word processor/editor has the tab stops/tab width set differently. Suggest using 4 spaces for each indent level as that is visible even with variable width fonts and allows for many indent levels across the page. – user3629249 Mar 29 '16 at 16:21

2 Answers2

1

This header file

#ifndef SUDOKUH_H_INCLUDED
#define SUDOKUH_H_INCLUDED

int numRows = 9;
int numCols = 9;
int i,j;

void displayTray (int numRows, int numCols, int pt[][numCols]);

#endif // SUDOKUH_H_INCLUDED

contains definitions of objects numRows and numCols. Thus these objects will be defined as many tiems as the header is included in compilation units.

So objects with the same name and external linkage will be defined several times.

To escape the error you can declare the objects with internal linkage. For example

#ifndef SUDOKUH_H_INCLUDED
#define SUDOKUH_H_INCLUDED

static const int numRows = 9;
static const int numCols = 9;

void displayTray (int numRows, int numCols, int pt[][numCols]);

#endif // SUDOKUH_H_INCLUDED

Also you should exclude from the header the definition

int i,j;

though it is posiible to have a tentative definition.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

the following code:

  1. has no 'magic' numbers
  2. in the display() function, fixes the display of the 'header' line
  3. drastically reduces the number of parameters to the display() function
  4. cleanly compiles
  5. uses unsigned variables when handling numbers that will only be >= 0
  6. stuffed everything in one file, for brevity
  7. does not define variable instances in the header file
  8. does not #include header files that are not used
  9. properly initializes the tray[][] array
  10. corrects the display() function to output lines separated by a newline

and now the code

#include <stdio.h>

//SudokuH.h

#ifndef SUDOKUH_H_INCLUDED
#define SUDOKUH_H_INCLUDED

#define NUM_ROWS (9)
#define NUM_COLS (9)

void displayTray (int pt[][ NUM_COLS ]);

#endif // SUDOKUH_H_INCLUDED
//#include "SudokuH.h"

int main(void)
{
    int tray[ NUM_ROWS ][ NUM_COLS ]={{ 0 }};
    displayTray(tray);
    return 0;
}



//SudokuS.c

#include <stdio.h>
//#include "SudokuH.h"

void displayTray(int pt[][ NUM_COLS ])
{
    printf(" |A|B|C|D|E|F|G|H|I|\n");

    for (size_t i=0; i<NUM_ROWS; i++)
    {
        printf("%lu|",i);
        for (size_t j=0; j<NUM_COLS; j++)
        {
            printf("%i|", pt[i][j]);
        }
        printf( "\n");
    }
}

the output looks like:

 |A|B|C|D|E|F|G|H|I|
0|0|0|0|0|0|0|0|0|0|
1|0|0|0|0|0|0|0|0|0|
2|0|0|0|0|0|0|0|0|0|
3|0|0|0|0|0|0|0|0|0|
4|0|0|0|0|0|0|0|0|0|
5|0|0|0|0|0|0|0|0|0|
6|0|0|0|0|0|0|0|0|0|
7|0|0|0|0|0|0|0|0|0|
8|0|0|0|0|0|0|0|0|0|
user3629249
  • 16,402
  • 1
  • 16
  • 17