C 2D Array rotating - c

I have a 2D pointer setup representing a grid, the grid consists of columns containing 1/0 or null columns (i.e. don't contain 1 in any cell). This function spins the grid by 90deg clockwise, and works except...
I think my malloc could be wrong as it works but I get many over picket-fence errors in dmalloc.
Am I allocating incorrect amounts of memory?
Also I wanted to swap the values of *width and *height to represent the new width and height of the grid but when I try this the program just segfaults on the second spin.

So *width is the dimension of orig's first dimension, so it should be the size of newg's second dimension.
Similarly *height should be the size of newg's first, and hence the two sets of malloc sizes have been flipped the wrong way around.
I think it would be clearer to name the values orig_max_x and orig_max_y, then it should be clear if the function uses the values the wrong way around.
newg = malloc (*height * sizeof(char *));
// Initialise each column
for (x = 0; x < *height; x++) {
newg[x] = malloc (*width);
for (y = 0; y < *width; y++)
newg[x][y] = 0;
}
Further, it should not free any of newg's storage if you want to return values from spin()
Edit: I still had some of those pesky *width and *height mixed. Sorry.
I strongly suggest the names should relate to the thing they talk about, orig_width,
orig_height would be have helped me read the code.
This is probably how I'd do it:
#include <stdio.h>
#include <stdlib.h>
char** alloc_rectangle(int *width, int *height);
void free_rectangle(char **orig, int *width);
char** spin (char **orig, int *width, int *height);
int main (int argc, const char * argv[]) {
int width = 20;
int height = 30;
char** orig = alloc_rectangle(&width, &height);
char** newg = spin(orig, &width, &height);
return 0;
}
char** alloc_rectangle(int *width, int *height)
{
char **newg = calloc (*width, sizeof(char *));
// Initialise each column
for (int x = 0; x < *width; x++) {
newg[x] = calloc (*height, sizeof(char));
}
return newg;
}
void free_rectangle(char **orig, int *width)
{
// free memory for old grid
for (int x = 0; x < *width; x++) {
if (orig[x] != NULL) {
free (orig[x]);
}
}
free (orig);
}
char** spin (char **orig, int *width, int *height)
{
int x;
int y;
char **newg = alloc_rectangle(height, width);
// Rotate
for (x = 0; x < *width; x++) {
for (y = 0; y < *height; y++)
if (orig[x] != NULL)
newg[*height - 1 - y][x] = orig[x][y];
}
return newg;
}
WARNING Untested code - some fun for all :-)
I don't think it is spin's job to free orig. I'd prefer it to just make space to hold the result of spinning. So to make things tidier, I pulled freeing a rectangle into its own function. Similarly, I'd always want the rectangles to be allocated consistently, so that would be its own function.

Take another look at the code that rotates the grid. I don't think you ever want to mix x and y coordinates, so an index like *width - 1 - y looks suspicious. For example, suppose *width = 3 and *height = 5. Then y ranges from 0 to 4, and you can end up with newg[3 - 1 - 4] = newg[-2].
Also, if you've allocated orig the same way you allocated newg you'll need to free it like this:
for (x=0; x < *width; x++) {
free (orig[x]); // Free the individual columns
}
free (orig); // Free the array of pointers.

I just wrote this up quickly and it seemed to work fine with the few tests I ran on it.
char **rotate(char **original, int *width, int *height)
{
int t_width = *height;
int t_height = *width;
char **newgrid = (char**)calloc(t_height, sizeof(char*));
for(int y = 0; y < t_height; y++)
{
newgrid[y] = (char*)calloc(t_width, sizeof(char));
for(int x = 0; x < t_width; x++)
newgrid[y][x] = original[x][y];
}
for(int y = 0; y < *height; y++)
free(original[y]);
free(original);
*width = t_width;
*height = t_height;
return newgrid;
}
Let me know if there are any problems.

Related

C Keep Getting Double Free, despite trying to free in same form as allocation

Hey I'm trying to do a simple machine learning application for school but I keep getting double free for some reason I cannot even fathom.
float * evaluate(Network net,float * in)
{
int i,j;
float * out;
Neuron cur_neu;
for(i=0,j=0;i<net.n_lay;i++) j = net.lay_sizes[i]>j?net.lay_sizes[i]:j; //Calculating the maximum lay size for output storage
out = (float *) malloc(j*sizeof(float));
for(i=0;i<net.n_lay;i++) //Cycling through layers
{
for(j=0;j<net.lay_sizes[i];j++) //Cycling through Neurons
{
cur_neu=net.matrix[i][j];
out[j] = cur_neu.af(cur_neu.w,in,net.lay_sizes[i-1]); //Storing each answer in out
}
for(j=0;j<net.lay_sizes[i];j++) in[j] = out[j]; //Transfering answers to in
}
return out;
}
float loss(Network net, float **ins_orig, int t_steps)
{
float **profecies;
float st = .5f;
int d_steps = 4;
int t, i, j;
int out_size = net.lay_sizes[net.n_lay - 1];
int in_size = net.lay_sizes[0];
float out = 0.0f;
float **ins;
/*
d_steps = Divination Steps: Number of time steps forward the network has to predict.
The size of the output layer must be d_steps*#ins (deconsidering any conceptual i/os)
t_steps = Total of Steps: Total number of time steps to simulate.
*/
//Copying ins
ins = (float **)malloc(t_steps * sizeof(float *));
for (i = 0; i < t_steps; i++) //I allocate memory for and copy ins_orig to ins here
{
ins[i] = (float *)malloc(in_size * sizeof(float));
for (j = 0; j < in_size; j++)
ins[i][j] = ins_orig[i][j];
}
//
profecies = (float **)malloc(t_steps * sizeof(float *));
for (t = 0; t < t_steps; t++)
{
profecies[t] = evaluate(net, ins[t]);
/*
Profecy 0:
[[a1,b1,c1,d1]
[e1,f1,g1,h1]
[i1,j1,k1,l1]]
Profecy 1:
[[e2,f2,g2,h2]
[i2,j2,k2,l2]
[m2,n2,o2,q2]]
Verification for:
t=0:
loss+= abs(a1-ins[t][0]+b2-ins[t][1]...)
t=1:
t=0:
loss+= abs(e1-ins[t][0]+f2-ins[t][1]...)
*/
for (i = 0; i < d_steps; i++) //i is distance of prediction
{
if (i <= t) // stops negative profecy indexing
{
for (j = 0; j < in_size; j++)
{
out += (ins[t][j] - profecies[t-i][j+in_size*i]) * (ins[t][j] - profecies[t-i][j+in_size*i]) * (1 + st*i); //(1+st*i) The further the prediction, the bigger reward
}
}
}
}
//Free ins
for (i = 0; i < t_steps; i++) //I try to free it here, but to no avail
{
free(ins[i]);
}
free(ins);
return out;
}
I realize it's probably something very obvious but, I can't figure it out for the life of me and would appreciate the help.
Extra details that probably aren't necessary:
evaluate just passes the input to the network (stored in ins) and returns the output
both inputs and outputs are stored in float "matrixes"
Edit: Added evaluate
In your loss() you allocate the same number of floats for each ins:
ins[i] = (float *)malloc(in_size * sizeof(float));
In your evaluate() you calculate the longest lay_size, indicating that it may NOT be net.lay_sizes[0]:
for(i=0,j=0;i<net.n_lay;i++) j = net.lay_sizes[i]>j?net.lay_sizes[i]:j; //Calculating the maximum lay size for output storage
Then you are writing out-of-bounds here:
for(j=0;j<net.lay_sizes[i];j++) in[j] = out[j]; //Transfering answers to in
From that point, your memory is corrupted.

Unable to read memory. Can't find what's wrong

I've got a piece of code, it's purpose is to draw a background image on one of the game levels. For this purpose I create this structure.
typedef struct crate_t {
int x = 0;
int y = 0;
int h = 0;
int w = 0;
int type = BACKGROUND;
}crate;
Then in the main function I create a 2D array
crate **Crates = (crate**)malloc(sizeof(crate)*(SCREEN_WIDTH / GrassBlock->w));
for (int i = 0; i <= SCREEN_HEIGHT/GrassBlock->h; i++) {
Crates[i] = (crate*)malloc(sizeof(crate)*(SCREEN_HEIGHT / GrassBlock->h));
}
and I pass it to the function counter = DrawLevelBG(screen, GrassBlock, Border, Crates);. The problem is that the function causes error. "Access violation writing location." at Obstacles[i][j].x = x;
int DrawLevelBG(SDL_Surface *screen, SDL_Surface *sprite, SDL_Surface *border, crate **Obstacles) {
int x = 0;
int y = 0;
int i = 0;
int j = 0;
bool condition = 0;
while (y < SCREEN_HEIGHT + sprite->h) {
DrawSurface(screen, sprite, x + (sprite->w / 2), y + (sprite->h / 2));
if (x >= SCREEN_WIDTH - sprite->w || x == 0 || y == 0 || y >= SCREEN_HEIGHT - sprite->h) {
DrawSurface(screen, border, x + (sprite->w / 2), y + (sprite->h / 2));
Obstacles[i][j].x = x;
Obstacles[i][j].y = y;
Obstacles[i][j].h = border->h;
Obstacles[i][j].w = border->w;
Obstacles[i][j].type = WALL;
i++;
if (x >= SCREEN_WIDTH - sprite->w) {
y += sprite->h;
x = 0;
j++;
condition = 1;
}
}
if (!condition) {
x += sprite->w;
}
condition = 0;
}
return i;
}
I know that these ones are caused by pointers not pointing actually to anything but I can't understand what's wrong here. Any help would be greatly appreciated. Thanks.
EDIT
I've changed my memory allocation piece of code so it looks like that now:
crate **Crates = (crate**)malloc(sizeof(crate*)*(SCREEN_WIDTH / GrassBlock->w)*(SCREEN_HEIGHT / GrassBlock->h));
for (int i = 0; i <= SCREEN_WIDTH/GrassBlock->w; i++) {
Crates[i] = (crate*)malloc(sizeof(crate)*(SCREEN_HEIGHT / GrassBlock->h));
}
According to all your replies guys. Unfortunately this doesnt solve the problem. +Important info, the function DrawLevelBG causes ERROR on the first iteration of loop.
In the first allocation you create an array from pointers. So you need to allocate memory for pointers:
crate **Crates = (crate**)malloc(sizeof(crate*)*(SCREEN_WIDTH / GrassBlock->w));
Thanks for all the help guys. The problem was iterators, not only did I make my 2D array SCREEN_HEIGHT wide and SCREEN_WIDTH high which was the opposite of what I wanted but aswell the iteration in DrawLevelBG was wrong as pointed out. I had to swap my "i" and "j" and make some corrections, so thanks alot Some programmer dude for pointing that out. Thanks alot.

Connect-N Board Game, crashing when Width is >> Height

I'm in the process of coding a Connect-N board game, and I'm almost finished and have gone through troubleshooting. My problem is now after changing some stuff my game crashes when the computer plays its move if the Width is too much greater than the height. There are two functions involved here, so I will paste them both.
Board
*AllocateBoard(int columns, int rows)
{
int **array= malloc(sizeof(int *) *columns);
int r = 0;
for ( r = 0; r < columns; ++r)
{
array[r] = malloc(sizeof(int) * rows);
}
int j = columns - 1;
int k = rows - 1;
int m = 0;
int n = 0;
for ( m = 0; m < j; ++m)
{
for ( n = 0; n < k; ++n)
{
array[m][n] = 0;
}
}
Board *board = malloc(sizeof(Board));
board->columns = columns;
board->rows = rows;
board->spaces = array;
return board;
}
This first function allocates the board to be a matrix Width * Height that the user passes in via the command line. It then initializes every space on the board to be zero, and then stores the columns, rows, and spaces into a Board structure that I've created. It then returns the board.
int
computerMakeMove(Board *board)
{ int RandIndex = 0;
int **spaces = board->spaces;
int columns = board->columns;
int *arrayoflegalmoves = malloc(sizeof(int) * (columns));
int columncheck = 0;
int legalmoveindex = 0;
while (columncheck <= columns - 1)
{
if (spaces[columncheck][0] == 0)
{
arrayoflegalmoves[legalmoveindex] = columncheck;
++legalmoveindex;
++columncheck;
}
else
{
++columncheck;
}
arrayoflegalmoves = realloc(arrayoflegalmoves, (legalmoveindex) * sizeof(int));
}
if (legalmoveindex == 1)
{
return arrayoflegalmoves[0];
}
else
{
RandIndex = rand() % (legalmoveindex);
return arrayoflegalmoves[RandIndex];
}
}
This second function is designed to make the computer randomly pick a column on the board. It does this by checking the value of the top row in each column. If there is a zero there, it will store this value in an array of legal moves, and then it increments the legalmoveindex. If there isn't, it skips the column and checks the next. It ends when it gets finished checking the final column. If there is only one legal move, it will play it. If there are more, it will select a random index from the array of legal moves (I run srand in the main) and then return that value. It will only ever attempt to play on a legal board, so that's not the problem. I am pretty confident the problem occurs in this function, however, as I call the functions as follows
printf("Taking the computers move.\n");
{printf("Taking computer's move.");
computermove = computerMakeMove(playerboard);
printf("Computer's move successfully taken.\n");
playerboard = MakeMove(playerboard, computermove, player);
printf("Computer's board piece successfully played.\n");
system("clear");
displayBoard(playerboard);
...;
}
and it prints
Aborted (core dumped)
immediately after it prints
"Taking computer's move."
Once again, my question is: why is my program crashing if the width is larger than the height when the computer plays?
Thanks.
Edit: I found the solution and I am stupid.
I realloc'd during the while loop.
The realloc should be the first thing outside of the while loop.
The answer for any future programmers who may have this problem:
Notice the
while (columncheck <= columns - 1)
{
if (spaces[columncheck][0] == 0)
{
arrayoflegalmoves[legalmoveindex] = columncheck;
++legalmoveindex;
++columncheck;
}
else
{
++columncheck;
}
arrayoflegalmoves = realloc(arrayoflegalmoves, (legalmoveindex) * sizeof(int));
}
has a realloc inside of it. The realloc should be moved to immediately outside of it, like so
while (columncheck <= columns - 1)
{
if (spaces[columncheck][0] == 0)
{
arrayoflegalmoves[legalmoveindex] = columncheck;
++legalmoveindex;
++columncheck;
}
else
{
++columncheck;
}
}
arrayoflegalmoves = realloc(arrayoflegalmoves, (legalmoveindex) * sizeof(int));
it is unusual to have the columns be the first index in an array.
having the first index of an array be columns leads to confusion
// suggest using camel case for all variable names, for readability
Board *AllocateBoard(int columns, int rows)
{
int **array= malloc(sizeof(int *) *columns); // add check that malloc successful
int r = 0;
for ( r = 0; r < columns; ++r)
{
array[r] = malloc(sizeof(int) * rows); // <-- add: check that malloc successful
}
int j = columns - 1; // this results in last column not initialized
int k = rows - 1; // this results in last row of each column not initialized
int m = 0; // column loop counter
int n = 0; // row loop counter
for ( m = 0; m < j; ++m)
{
for ( n = 0; n < k; ++n)
{
array[m][n] = 0;
}
}
Board *board = malloc(sizeof(Board)); // <-- add: check if malloc successful
board->columns = columns;
board->rows = rows;
board->spaces = array;
return board;
} // end function: AllocateBoard
// why is this only looking at the first row of each column?
int computerMakeMove(Board *board)
{
int RandIndex = 0;
int **spaces = board->spaces;
int columns = board->columns;
int *arrayoflegalmoves = malloc(sizeof(int) * (columns)); // <-- add check that malloc successful
int columncheck = 0;
int legalmoveindex = 0;
while (columncheck <= columns - 1)// should be: for(; columncheck < columns; columncheck++ )
{
if (spaces[columncheck][0] == 0)
{ // then first row of column is zero
arrayoflegalmoves[legalmoveindex] = columncheck;
++legalmoveindex;
++columncheck; // <-- remove this line
}
else // remove this 'else' code block
{
++columncheck;
} // end if
arrayoflegalmoves = realloc(arrayoflegalmoves, (legalmoveindex) * sizeof(int));
// <-- 1) use temp int*, in case realloc fails
// <-- 2) if realloc successful, update arrayoflegalmoves
// <-- 3) the code is not checking each row of each column,
// so the original malloc is more than plenty
// so why bother to realloc
// <-- 4) if legalmoveindex is 0 then realloc returns NULL
} // end while
// in following, what about when zero moves found? probably should return NULL
if (legalmoveindex == 1)
{ // only one column[row0] found to contain 0
return arrayoflegalmoves[0];
}
else
{
RandIndex = rand() % (legalmoveindex);
return arrayoflegalmoves[RandIndex]; // if zero moves found, this returns a
// de-reference to address 0
// which would result in a seg fault event
} // end if
} // end function: computerMakeMove

Syntax not clear about pointers and matrix

i am coding in C and i have to work with png images, so i work with libpng library. In my project i use this structure:
png_bytep *row_pointers; /* <-- to declare the pointer that will contain the image
and this to initialize the pointer to contain the image. */
row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height);
for(int y = 0; y < height; y++) {
row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png,info));
}
My problem is: after this piece of code my image is copyed in row_pointers and i want to copy it in a png_byte map[x][y] so i can work easly pixel for pixel.
Someone can help me?
Thanks
Ok. That is pointer to pointer!
png_bytep = pointer to png_byte
If you eliminate png_bytep and just use png_byte your code will look like this.
int height = 10;
int width = 20;
png_byte **row_pointers;
row_pointers = (png_byte**)malloc(sizeof(png_byte*) * height); <-- This is basically your number of rows.. ie height of your matrix.
for(int y = 0; y < height; y++)
{
row_pointers[y] = (png_byte*)malloc(sizeof(png_byte)*width); <-- This is representing number of elements in each row.. so width.
}
Assuming your structure have two ints x and y. you must be filing data as below..
for(int i=0;i< height;i++)
{
for (int j=0;j<width;j++)
{
row_pointers[i][j].x = i*j;
row_pointers[i][j].y = i*j;
}
}
Assuming your map also have similar structure. This is how you copy data..
for(int i=0;i< height;i++)
{
for (int j=0;j<width;j++)
{
map[i][j].x = row_pointers[i][j].x;
map[i][j].y = row_pointers[i][j].y;
}
}
Have a look at pnm2png.c in libpng's contrib/pngminus directory.
In this code, "png_pixels" is a simple array that holds all the pixels, and row_pointers is an array of pointers that point to the beginning of each row within png_pixels:
/* row_bytes is the width x number of channels x (bit-depth / 8) */
row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2);
png_pixels = (png_byte *) malloc (row_bytes * height * sizeof (png_byte))
/* set the individual row_pointers to point at the correct offsets */
for (i = 0; i < (height); i++)
row_pointers[i] = png_pixels + i * row_bytes;
/* now we can go ahead and just read the whole image */
png_read_image (png_ptr, row_pointers);
Once png_read_image completes, you can easily work with your pixels in the png_pixels array.
Notice that there is only one "malloc", which allocates png_pixels. Instead of doing a separate "malloc" for each row, this code calculates the values of the row_pointers.

Changing fixed bi-dimensional array to take size given at runtime

I've been trying to wrap my head around this the whole day...
The code that I have so far works as planed, the idea is that I'll have to change tCell * cells[3][5]; to take a size that's given at runtime. What changes do I need to make to retain the functionality?
typedef struct {
int active;
} tCell;
typedef struct {
tCell * cells[3][5];
} tGrid;
// creates a grid and initialize all the cells to NULL
tGrid *init_grid()
{
tGrid *grid= malloc(sizeof(tGrid));
if(grid == NULL)
exit(127); // failed to malloc
int i, j;
for(i=0; i < 3; i++)
for(j=0; j < 5; j++)
grid->cells[i][j]= NULL;
return grid;
}
// adds a cell to the grid
void add_cell(tGrid *grid)
{
tCell cell;
int y = rand() % 4;
if(grid->cells[0][y] != NULL)
exit(127); // cell is taken
cell.active = 1;
grid->cells[0][y] = &cell;
}
void remove_cell(tGrid *grid, int x, int y)
{
if(x < 0 || x > 3 || y < 0 || y > 5)
exit(127); // out of bounds
grid->cells[x][y]= NULL;
}
Basically, init_grid will have to take x and y as parameters:
tGrid *init_grid(int x, int y);
But then, how do I change tGrid struct definition? Whatever I've tried so far yielded a compiler error (e.g. tCell * cells[][];)
On a slightly related note, how do you read "tCell * cells[3][5];" outloud?
Note:
this is a C question
I'm using gcc 4.1 to compile the code
Easy.
typedef struct {
int rows;
int columns;
tCell **cells;
} tGrid;
And allocating:
tGrid *pGrid = (pGrid*)malloc(sizeof(tGrid));
/* check results etc */
pGrid->rows = rows;
pGrid->columns = columns;
pGrid->cells = (tCell**)malloc(sizeof(tCell*)*rows);
/* check results */
do{
pGrid->cells[rows-1] = (tCell*)malloc(sizeof(tCell)*columns);
/* check results */
} while (--rows);
Done.
Or, you can also do:
typedef struct {
int rows;
int columns;
tCell *cells;
} tGrid;
/*****whatever in the middle ***********/
pGrid->cells = (tCell*)malloc(sizeof(tCell)*rows*columns);
instead of the do-while loop. The difference is that in the first case, each row will be a separate array in the memory, which may be useful when handling the thing.
Of course, in the end, for each malloc there has to be a free.

Resources