2

I am new to C and have run into this issue twice now.

The problem is that I am getting an access violation error when attempting to run the following program. The exception is thrown in the initialize_board() function. I put a comment on the specific line.

Any insight from those with more experience would be appreciated!

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

/* global variables */
const int BOARD_SIZE = 3;
const char X = 'X';
const char O = 'O';
char** active_board;

//creates a square 2d array of size BOARD_SIZE
void create_board() {
    //ptrs to array of chars
    active_board = (char*)malloc(sizeof(char*)*BOARD_SIZE);
    for (int i = 0; i < BOARD_SIZE; i++) {
        active_board[i] = (char)malloc(sizeof(char) * BOARD_SIZE);
    }
}

//fills board with either char X or O
void initialize_board(char symbol) { //symbol:= X or O
    for (int i = 0; i < BOARD_SIZE; i++) {
        for (int j = 0; j < BOARD_SIZE; j++) {
            active_board[i][j] = symbol;// <---EXCEPTION THROWN HERE
        }
    }
}

int main() {
    create_board();
    initialize_board(X);

    return 0;
}`
  • 1
    Your casts are wrong, you want `(char**)` and `(char*)` respectively in the `create_board` function (of course only the 2nd really causes a problem). The compiler should warn you about this. – Qubit Sep 13 '18 at 10:10
  • 1
    Just as a general tipp, you should use compiler flags to add more warnings, e.g., if you use GCC -Wall -pedantic or even -Werror (warnings as errors). – Benjamin Maurer Sep 13 '18 at 10:23
  • 1
    `sizeof(char` is guaranteed `1`, so it' not necessary. And don't cast the result of `malloc` & friends or `void *` in general. And if you want a 2D array, why don't you use one, but write overly complicated code? (no, a _pointer to pointer_ is **not** a 2D array and cannot represent one, whatever your teacher might have told you). – too honest for this site Sep 13 '18 at 10:44
  • This question needs to be a canonical example of what bad things happen when you cast the results of `malloc()`. `active_board[i] = (char)malloc(...` truncates the pointer returned by `malloc()` down to a single byte, but since you cast it explicitly there's a good chance you won't even get a compiler warning. And off-topic, but using nested loops with a `malloc()` in the loop to allocate a multidimensional "array" is just about the least efficient way to allocate memory possible. See https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays for an example. – Andrew Henle Sep 13 '18 at 11:17

1 Answers1

2

The problem are those casts

active_board = (char*)malloc(sizeof(char*)*BOARD_SIZE); /* Must return `char **` */
for (int i = 0; i < BOARD_SIZE; i++) {
    active_board[i] = (char)malloc(sizeof(char) * BOARD_SIZE); /* Must return `char *` */
}

Don't cast malloc:

active_board = malloc(sizeof(char*)*BOARD_SIZE);
for (int i = 0; i < BOARD_SIZE; i++) {
    active_board[i] = malloc(sizeof(char) * BOARD_SIZE);
}
David Ranieri
  • 39,972
  • 7
  • 52
  • 94