Yitzak Hernandez
Yitzak Hernandez

Reputation: 357

Two Dimensional Arrays with User Input

I'm making a crossword puzzle grid in which the user enters first the dimensions of the grid then each line separated by a space or enter. The program takes in each line and puts each letter of the line in a spot on the grid[][]. So far I've only managed to make my grid work for a dimension 4x4 or smaller, if I make it any bigger any letter found in grid[0][i] just spits out garbage. If I printf the grid after each iteration of the loop its correct, but if I go back and check its not. Anyone got any ideas?

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

int main (){

    int i, j, row, column;

    scanf("%i", &row);
    scanf("%i", &column);

    char *userInput = malloc (sizeof(char)*column);
    char **grid = malloc(sizeof(char)*column);

    for(i=0; i<row; i++){
        scanf("%s", userInput);
        grid[i] = (char*) malloc (row *sizeof(char));
        for (j=0; j<column; j++){
            grid[i][j] = userInput[j];
        }
    }

    // double check to see if the grid is correct.
    printf("%c", grid[0][2]);

return 0;
}

Upvotes: 1

Views: 164

Answers (2)

TeasingDart
TeasingDart

Reputation: 381

Your grid malloc is incorrect. It should be

char **grid = malloc(sizeof(char*)*column);

Grid is an array of "pointer to char" not "char". Seeing garbage is the classic symptom of a buffer overrun (or in this case, buffer under-allocation).

Also, while not strictly necessary if you are careful, all character buffers should be allocated with an extra byte for the string terminator (zero).

Upvotes: 0

Jack
Jack

Reputation: 133577

I think you are mixing indices

  • you allocate column amount of char* pointers
  • then you iterate on row (when it should be column) and allocate a row amount of char for each index
  • then you fill that char[row] with a string which has column length instead that row

Since you are reading column characters I assume you want a row x column matrix, what you should do is something like

int i, j, row, columnM
char** grid = malloc(row*sizeof(char*));
char* userInput = malloc(column);

for (i = 0; i < row; ++i)
{
  grid[i] = malloc(column);
  ..
  memcpy(grid[i], userInput, column);
}

Actually you don't need sizeof(char) in allocations since a char is guaranteed to be 1 byte by the standard.

Mind that scanf will write a nul terminator at the end of the string read regardless the size of the buffer. So you should provide at least column+1 bytes to read to. This won't prevent the user from entering more characters and cause a buffer overflow, check my comment.

Upvotes: 2

Related Questions