Updating a 2D array in a function using pointers [closed] - c

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 days ago.
This post was edited and submitted for review 4 days ago.
Improve this question
I have been working on this school assignment project for a while now. I have the template program and what I currently have. I am just really unsure on how to solve my issue.
The project is to have 'turtles' print out a message depending on the command given. In this case, the commands would print out 'BOB'. For me, I have to code some of the turtleDraw code, and all of the turtleMove and displayFloor functions. I posted both the template program, and what I currently have.
I think my errors are in the moveTurtle function. Unsure how I would get the array to move the right number of indexes.
The given program
void turtleDraw(const int[]); // main function responsible for executing cmds
// main supplies data to be passed to turtleDraw() function
int main()
{
int commands[] = { 5, 5, 4, 5, 9, 2, // go to start of first letter and put pen down
// B
5, 12, 1, 3, 5, 1, 4, 2, 5, 1, 1, 3, 5, 1, 2, 5, 2, 1, 3, 5, 1, 4, 2, 5, 1, 1, 3, 5, 1, 2, 5, 11, 3, 5, 5,
1, 3, 5, 12, 3, 5, 5, 5, 1, 4, 2, 5, 1, 1, 3, 5, 1, 2, 5, 2, 1, 3, 5, 1, 4, 2, 5, 1, 1, 3, 5, 1, 2, 5, 11, 3, 5, 5,
1, 5, 5, 3, 5, 22, 2, // go to start of next letter and put pen down
// O
5, 10, 1, 3, 5, 1, 4, 2, 5, 1, 1, 3, 5, 1, 2, 5, 7, 1, 3, 5, 1, 4, 2, 5, 1,
1, 3, 5, 1, 2, 5, 10, 1, 3, 5, 1, 4, 2, 5, 1, 1, 3, 5, 1, 2, 5, 7, 1, 3, 5, 1, 4, 2, 5, 1,
1, 3, 5, 19, 2, // go to start of next letter and put pen down
// B
5, 12, 1, 3, 5, 1, 4, 2, 5, 1, 1, 3, 5, 1, 2, 5, 2, 1, 3, 5, 1, 4, 2, 5, 1, 1, 3, 5, 1, 2, 5, 11, 3, 5, 5,
1, 3, 5, 12, 3, 5, 5, 5, 1, 4, 2, 5, 1, 1, 3, 5, 1, 2, 5, 2, 1, 3, 5, 1, 4, 2, 5, 1, 1, 3, 5, 1, 2, 5, 11, 3, 5, 5,
// Test program bound checking and add border in the process
// Uncomment next line when ready to test out of bounds checking
//1, 5, 100, 2, 4, 5, 100, 4, 5, 100, 4, 5, 100, 4, 5, 100, 4, 5, 100,
1, 6, 9 }; // finish off
// Invoke function which will execute commands
turtleDraw(commands);
// Time to go home
}
// define 2 enum types
enum TCmnds { PEN_UP = 1, PEN_DWN = 2, TURN_RIGHT = 3, TURN_LEFT = 4, MOVE = 5, DISPLAY = 6, END_OF_DATA = 9 };
enum Dirs { BEGIN_VALUE, NORTH, EAST, SOUTH, WEST, END_VALUE };
#define NROWS 22 // number of rows in floor
#define NCOLS 70 // number of colums in floor
#define TRUE 1
#define FALSE 0
const unsigned int STARTING_ROW = 0; // row that turtle will start in
const unsigned int STARTING_COL = 0; // column that turtle will start in
const enum Dirs STARTING_DIRECTION = SOUTH; // direction that turtle
// will be facing at the start
const short STARTING_PEN_POSITION = FALSE; // Pen will be up when
// program starts
// 0 (false) means pen up,
// 1 (true) means pen down
// some more function prototypes
void displayFloor(const short[][NCOLS]);
void moveTurtle(short [][NCOLS], const int , const enum Dirs , const short , int* , int* );
// turtleDraw() - function responsible for executing commands
void turtleDraw(const int cmds[])
{
// Define and initialize some important variiables
// The 2D array floor will represent the surface that the turtle is travelling
// over and there by creating the pattern we will eventually print out.
short floor[NROWS][NCOLS] = { FALSE }; //init to all FALSE (0).
enum Dirs direction = STARTING_DIRECTION; // used to represent current direction that the turtle is moving
unsigned int row = STARTING_ROW; // used to represent current row that turtle is at
unsigned int col = STARTING_COL; // used to represent current column that turtle is at
short pen = STARTING_PEN_POSITION; // starting position of pen (up or down)
// 0 is up, 1 is down
int cmdNo = 0; // The position in cmds array we are currently processing
// The following do-while loop is the main loop of this program
// We will stay in this loop as long as we are processing commands from the cmds[] array
do { // until END_OF_DATA is encountered
switch (cmds[cmdNo]) { // Switch statment that processes commands
case PEN_UP: // Pen up
pen = FALSE;
break;
case PEN_DWN: // Pen down
// STUDENT PROVIDES THIS CODE
case TURN_RIGHT: // Turn right
++direction; // for example, change from NORTH to EAST
if (direction >= END_VALUE ) // in case we turn right when facing WEST
{
direction = NORTH;
}
break;
case TURN_LEFT: // Turn left
// STUDENT PROVIDES THIS CODE
case MOVE: // Move forward
++cmdNo; // move to next command in the command array
// we need next value to know how many spaces to move
// We pass pointers to row and col below so that when we update in moveTurtle()
// they are updated here in turtleDraw() as well.
moveTurtle(floor, cmds[cmdNo], direction, pen, &row, &col); // move turtle as required
// and update floor as req.
break; // end of case MOVE:
case DISPLAY: // display the floor matrix
displayFloor(floor);
break;
case END_OF_DATA: // end of data reached
break; // no action required, will exit do-while loop automatically
default: // should never get here !!!
puts("\n\nERROR - invalid command encountered in"
" turtleDraw() switch statement.\n\n");
return; // major error, so go home
} // end of switch statment
++cmdNo; // move to next command
} while (cmds[cmdNo] != END_OF_DATA); // repeat until end of data is reached
}
// moveTurtle() - responsible for moving the turtle on the floor and modifying floor if pen is down.
// This function is passed pointers to row and col because they need to be passed by reference
// because this function must update the row and col when moving turtle. Note that
// floor is also passed by reference, but because an arry name is a pointer, the array
// is automatically passed by reference.
void moveTurtle(short floor [][NCOLS], const int numOfMoves, const enum Dirs currDir, const short penPos, int * rowPtr, int * colPtr)
{
// STUDENT PROVIDES THIS CODE
}// end of moveTurtle()
// Responsible for displaying the floor
void displayFloor(const short floorSurface[][NCOLS])
{
// STUDENT PROVIDES THIS CODE
} // end of displayFloor()
This is what I currently have.
void turtleDraw(const int[]); // main function responsible for executing cmds
// main supplies data to be passed to turtleDraw() function
int main()
{
int commands[] = { 5, 5, 4, 5, 9, 2, // go to start of first letter and put pen down
// B
5, 12, 1, 3, 5, 1, 4, 2, 5, 1, 1, 3, 5, 1, 2, 5, 2, 1, 3, 5, 1, 4, 2, 5, 1, 1, 3, 5, 1, 2, 5, 11, 3, 5, 5,
1, 3, 5, 12, 3, 5, 5, 5, 1, 4, 2, 5, 1, 1, 3, 5, 1, 2, 5, 2, 1, 3, 5, 1, 4, 2, 5, 1, 1, 3, 5, 1, 2, 5, 11, 3, 5, 5,
1, 5, 5, 3, 5, 22, 2, // go to start of next letter and put pen down
// O
5, 10, 1, 3, 5, 1, 4, 2, 5, 1, 1, 3, 5, 1, 2, 5, 7, 1, 3, 5, 1, 4, 2, 5, 1,
1, 3, 5, 1, 2, 5, 10, 1, 3, 5, 1, 4, 2, 5, 1, 1, 3, 5, 1, 2, 5, 7, 1, 3, 5, 1, 4, 2, 5, 1,
1, 3, 5, 19, 2, // go to start of next letter and put pen down
// B
5, 12, 1, 3, 5, 1, 4, 2, 5, 1, 1, 3, 5, 1, 2, 5, 2, 1, 3, 5, 1, 4, 2, 5, 1, 1, 3, 5, 1, 2, 5, 11, 3, 5, 5,
1, 3, 5, 12, 3, 5, 5, 5, 1, 4, 2, 5, 1, 1, 3, 5, 1, 2, 5, 2, 1, 3, 5, 1, 4, 2, 5, 1, 1, 3, 5, 1, 2, 5, 11, 3, 5, 5,
// Test program bound checking and add border in the process
// Uncomment next line when ready to test out of bounds checking
//1, 5, 100, 2, 4, 5, 100, 4, 5, 100, 4, 5, 100, 4, 5, 100, 4, 5, 100,
1, 6, 9 }; // finish off
// Invoke function which will execute commands
turtleDraw(commands);
// Time to go home
}
// define 2 enum types
enum TCmnds { PEN_UP = 1, PEN_DWN = 2, TURN_RIGHT = 3, TURN_LEFT = 4, MOVE = 5, DISPLAY = 6, END_OF_DATA = 9 };
enum Dirs { BEGIN_VALUE, NORTH, EAST, SOUTH, WEST, END_VALUE };
#define NROWS 22 // number of rows in floor
#define NCOLS 70 // number of colums in floor
#define TRUE 1
#define FALSE 0
const unsigned int STARTING_ROW = 0; // row that turtle will start in
const unsigned int STARTING_COL = 0; // column that turtle will start in
const enum Dirs STARTING_DIRECTION = SOUTH; // direction that turtle
// will be facing at the start
const short STARTING_PEN_POSITION = FALSE; // Pen will be up when
// program starts
// 0 (false) means pen up,
// 1 (true) means pen down
// some more function prototypes
void displayFloor(const short[][NCOLS]);
void moveTurtle(short [][NCOLS], const int , const enum Dirs , const short , int* , int* );
// turtleDraw() - function responsible for executing commands
void turtleDraw(const int cmds[])
{
// Define and initialize some important variiables
// The 2D array floor will represent the surface that the turtle is travelling
// over and there by creating the pattern we will eventually print out.
short floor[NROWS][NCOLS] = { FALSE }; //init to all FALSE (0).
enum Dirs direction = STARTING_DIRECTION; // used to represent current direction that the turtle is moving
unsigned int row = STARTING_ROW; // used to represent current row that turtle is at
unsigned int col = STARTING_COL; // used to represent current column that turtle is at
short pen = STARTING_PEN_POSITION; // starting position of pen (up or down)
// 0 is up, 1 is down
int cmdNo = 0; // The position in cmds array we are currently processing
// The following do-while loop is the main loop of this program
// We will stay in this loop as long as we are processing commands from the cmds[] array
do { // until END_OF_DATA is encountered
switch (cmds[cmdNo]) { // Switch statment that processes commands
case PEN_UP: // Pen up
pen = FALSE;
break;
case PEN_DWN: // Pen down
pen = TRUE; // STUDENT PROVIDES THIS CODE //i DID
break;
case TURN_RIGHT: // Turn right
++direction; // for example, change from NORTH to EAST
if (direction >= END_VALUE ) // in case we turn right when facing WEST
{
direction = NORTH;
}
break;
case TURN_LEFT: // Turn left //I did
--direction;
if (direction <= BEGIN_VALUE) {
direction = SOUTH;
}
// STUDENT PROVIDES THIS CODE
case MOVE: // Move forward
++cmdNo; // move to next command in the command array
// we need next value to know how many spaces to move
// We pass pointers to row and col below so that when we update in moveTurtle()
// they are updated here in turtleDraw() as well.
moveTurtle(floor, cmds[cmdNo], direction, pen, &row, &col); // move turtle as required
// and update floor as req.
break; // end of case MOVE:
case DISPLAY: // display the floor matrix
displayFloor(floor);
break;
case END_OF_DATA: // end of data reached
break; // no action required, will exit do-while loop automatically
default: // should never get here !!!
puts("\n\nERROR - invalid command encountered in"
" turtleDraw() switch statement.\n\n");
return; // major error, so go home
} // end of switch statment
++cmdNo; // move to next command
} while (cmds[cmdNo] != END_OF_DATA); // repeat until end of data is reached
}
// moveTurtle() - responsible for moving the turtle on the floor and modifying floor if pen is down.
// This function is passed pointers to row and col because they need to be passed by reference
// because this function must update the row and col when moving turtle. Note that
// floor is also passed by reference, but because an arry name is a pointer, the array
// is automatically passed by reference.
void moveTurtle(short floor [][NCOLS], const int numOfMoves, const enum Dirs currDir, const short penPos, int* rowPtr, int* colPtr)
{
int tempNumOfMoves = numOfMoves;
//int row = *rowPtr;
if (currDir == EAST) //right
{
while (*rowPtr != numOfMoves) {
++(*rowPtr);
//++row;
//printf("Row %d\n", *rowPtr);
} //once it equals the number of moves
if (penPos == TRUE)
{
int i;
for (i = 0; i < numOfMoves; i++) {
floor[*rowPtr][*colPtr] = 1;
//end for
} //end if
} //end if
else {
int i;
for (i = 0; i < numOfMoves; i++) {
floor[*rowPtr][*colPtr] = 0;
printf("Row %d, Column %d\n", *rowPtr, *colPtr);
}
}
}
else if (currDir == SOUTH) //down
{
while (*rowPtr != numOfMoves) {
++(*rowPtr);
} //once it equals the number of moves
if (penPos == TRUE)
{
int i;
for (i = 0; i < numOfMoves; i++) {
floor[*rowPtr][*colPtr] = 1;
printf("Row %d, Column %d", *rowPtr, *colPtr);
//end for
} //end if
} //end else if
else {
int i;
for (i = 0; i < numOfMoves; i++) {
floor[*rowPtr][*colPtr] = 0;
printf("Pen Down Row %d, Column %d\n", *rowPtr, *colPtr);
}
}
}
else if (currDir == NORTH) //north
{
while (*colPtr != numOfMoves) {
--(*colPtr);
//++row;
printf("Column %d\n", *colPtr);
}
printf("%d\n", *colPtr);
if (penPos == TRUE)
{
int i;
for (i = 0; i < numOfMoves; i++) {
{
floor[*rowPtr][*colPtr] = 1;
} //end for
} //end if
} //end else if
}
else //WEST
{
while (*rowPtr != numOfMoves) {
--(*rowPtr);
//++row;
printf("Row %d\n", *rowPtr);
}
if (penPos == TRUE)
{
int i;
for (i = 0; i < numOfMoves; i++) {
{
floor[*rowPtr][*colPtr] = 1;
} //end for
} //end if
} //end else if
}
//for (int i = 0; i < NROWS())
//
// STUDENT PROVIDES THIS CODE
}// end of moveTurtle()
// Responsible for displaying the floor
void displayFloor(const short floorSurface[][NCOLS])
{
for (int i = 0; i < NROWS; i++) {
for (int j = 0; j < NCOLS; j++) {
if (floorSurface[i][j] == 1) {
printf("%s", "*");
}
else {
printf("%s", " ");
}
}
printf("\n");
}
// STUDENT PROVIDES THIS CODE
} // end of displayFloor()
The outputs is supposed to look like
enter image description here

Related

Making sure a user's input matches characters generated by my program

This is for Homework
I'm programming a simplified game of scrabble where I have my program randomly generate characters then the user would try and create a word from those generated characters, then get a score afterwards. The issue I'm having is making sure the user is actually using the characters provided. I have no clue on how to approach this problem. I don't need any code but hints would be appreciated or even links for a point to start at. Thanks for any help!
EDIT - About half my program [The part that creates the letter set]
void generate_letter_set(int letter_set[] , int size_let , int num_let)
{
int arr[N];
const char let[] =
{'K','J','X','Q','Z','B','C','M','P','F','H','V','W','Y','G','L','S','U','D','N','R','T','O','A','I','E'};
const int freq[] =
{ 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 4, 4, 4, 6, 6, 6, 8, 9, 9, 12 };
int score[] =
{ 5, 8, 8, 10, 10, 3, 3, 3, 3, 4, 4, 4, 4, 4, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1};
int index = 0;
for(int i = 0 ; i < 26 ; i++) {
for(int f = 0 ; f < freq[i]; f++) {
arr[index++] = let[i]; //All the 96 letters are stored in let[i]
//printf("%c " , let[i]); // Created the letter bank for all the letters
}
} int letter;
printf("Your letters are: ");
for(int l = 0; l < 7; l++){
letter = rand() % 97;
printf("%c ", arr[letter]);
}
}
There are a lot of different ways to search an array for certain characters. The basis of what you need is a very simple search function.
One simple solution would be to use two nested for loops. Assuming let[] is your 'haystack' to check and word is your user input:
// Check each letter of word[]...
for (int ii = 0; ii <= lengthOfUserInput; ii++)
{
char characterToValidate = word[ii];
// ... for not existing in let[]
for (int jj = 0; jj <= lengthOfStringOfValues; jj++)
{
if (characterToValidate != let[jj])
}
}

Initialize elements of GSL matrix

I have allocated a large gsl_matrix and would like to allocate all its elements with known float values. Is there a way to do it without using gsl_matrix_set for each element? I am looking for the equivalent of fortran's reshape function to initialize a matrix.
A = reshape( (/0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7,
0, 1, 2, 3, 4, 5, 6, 7/), (/ 8, 8/) )
Matrices only support limited setting of all values, that is by gsl_matrix_set_all, gsl_matrix_set_zero or gsl_matrix_set_identity.
However, you can create and initialise an array and then create a matrix view from that using gsl_matrix_view_array, gsl_matrix_const_view_array, gsl_matrix_view_array_with_tda or gsl_matrix_const_view_array_with_tda. (Matrix views are common in GSL. For example, they are used to express sub-matrices returned by gsl_matrix_submatrix.) The matrix view is a struct which contains a field matrix upon which you execute the gsl_matrix methods you wish to apply.
For example, compile with gcc matrixview.c -lgsl -lgslcblas the following file matrixview.c:
#include <stdio.h>
#include <gsl/gsl_matrix.h>
#define rows 2
#define cols 3
int main () {
const double data[rows*cols] = {
0.0, 0.1, 0.2,
1.0, 1.1, 1.2,
};
const gsl_matrix_const_view mat = gsl_matrix_const_view_array( data, rows, cols );
for ( size_t row = 0; row < rows; ++row ) {
for ( size_t col = 0; col < cols; ++col ) {
printf( "\t%3.1f", gsl_matrix_get( &mat.matrix, row, col ) );
}
printf( "\n" );
}
}

Method to test if arrays are the reverse of each other not passing test

I'm supposed to make a method to test if two arrays have the same values in reverse order.
public static boolean areReversed (int [] t , int [] q)
{
boolean identical = false;
if(t.length != q.length){ identical = false;}
else{
for(int x = (t.length -1) , y = 0; -1 < x; x-- , y++)
{
if(t[y] == q[x])
{
identical = true;
}
}
}
return identical;
}
I test it by running it through these if statements with the following pre-determined arrays
int[] a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
int[] b = {0, 9, 8, 7, 6, 5, 4, 3, 2, 1};
int[] c = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int[] d = {9, 8, 7, 6, 5, 4, 3, 2, 1};
int[] e = {1, 2, 3, 4, 5, 4, 3, 2, 1};
int[] f = {1, 2, 3, 4, 4, 3, 2, 1};
int[] g = {1, 3, 5, 7, 9, 0, 2, 4, 6, 8};
int[] h = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
int[] i = {1, 1, 3, 3, 5, 5, 7, 7, 9, 9};
//test for areReversed, uncomment the next two lines to test your method
if(areReversed(a, b) && !areReversed(a, g) && !areReversed(a, c)) System.out.println("Basic areReversed method test PASSED");
else System.out.println("Basic areReversed method test FAILED");
My method doesn't pass the test, am I making an oversight somewhere in my code?
Yes, you are indexing to two arrays in the same order. You are essentially checking that they are equal, not that they are the reverse of each other.
Also, remember that a function can return at any point Think about this and think about how you could make your function more efficient in a case where the arrays look like this:
[1,2,3] and [4,2,4].
How many comparisons do you actually need to make before you can tell us the arrays are not the same.
This is what you should do:
public static boolean areReversed (int [] t , int [] q)
{
if(t.length != q.length) return false;
for(int x = (t.length -1) , y = 0; -1 < x; x-- , y++)
{
if(t[y] != q[x]) return false;
}
return true;
}
Note that I'm returning false from the method as and when it is known that the reversed arrays are unequal. Hence, at the end, if false isn't returned yet, the arrays have to be reversed equal, and thus, true is returned.

Removing row and column of matrix after looking for a value (C)

I made a question some hours ago but I get myself in a mess on what I had to do after finishing what I was asking on that question. All the solutions that the people gave me were ok, but useless for what I was really looking for as I didn't wrote the question as it has to be. I've to save an important position of a value, and it wasn't necessary to be saved on the other question to solve the problem. So here's the proper one.
(everything's is explained with an example above, understanding it is easy) I've a 8x8 matrix, and after choosing the row I desire, I want to get the three minimum elements of it, and choose one of this three randomly. Then, remove the row and column that contains this number. The thing is that I'dont know how to handle those three elements and remove the columns/rows. I just know how to get the minimum element, that is the following code.
int pieza[ROWS][COLS] = {
0, 2, 2, 5, 3, 2, 1, 1,
0, 4, 5, 2, 4, 3, 0, 0,
0, 4, 2, 2, 1, 2, 3, 2,
0, 3, 1, 5, 1, 2, 3, 4,
2, 5, 6, 5, 3, 1, 2, 7,
8, 2, 0, 0, 0, 2, 1, 1,
1, 2, 2, 1, 1, 6, 3, 4,
0, 1, 3, 2, 0, 0, 0, 0,
};
int myrow = 3; // the row I want to analyze
int index;
int min=0;
for (index=0;index<8;index++) {
printf("%d", piezas[myrow][index] );
if(piezas[myrow][index]<min)
min=piezas[myrow][index];
printf("\t\t");
}
printf("min: %d", min);
This is what I want to do. If the initial matrix is (which is always a nxn matrix):
{
0, 2, 2, 5, 3, 2, 1, 1,
0, 4, 5, 2, 4, 3, 0, 0,
0, 4, 2, 2, 1, 2, 3, 2,
0, 3, 1, 5, 1, 2, 3, 4,
2, 5, 6, 5, 3, 1, 2, 7,
8, 2, 0, 0, 0, 2, 1, 1,
1, 2, 2, 1, 1, 6, 3, 4,
0, 1, 3, 2, 0, 0, 0, 0,
};
And I choose row number 3:
0, 3, 1, 5, 1, 2, 3, 4,
The algorithm must choose the three minimum elements of that row.
0, 1, 1
And choose randomly one of these three. If, for example, it choose the first 'one'...
0, **1**, 1
... the algorithm must go to the 3th column of that line (becaue that was the position that was that '1') and remove the row and column, so the output matrix will be as follows, one dimension less than the original matrix (beucase you have removed a row and a column):
{
0, 2, 5, 3, 2, 1, 1,
0, 4, 2, 4, 3, 0, 0,
0, 4, 2, 1, 2, 3, 2,
2, 5, 5, 3, 1, 2, 7,
8, 2, 0, 0, 2, 1, 1,
1, 2, 1, 1, 6, 3, 4,
0, 1, 2, 0, 0, 0, 0,
};
I only know how to arrive to the line, but I'm having problems to handle three minimums because I'm having tons of problems pointers and I'm not a lot into C. Thanks in advance
Example to be sorted with the number of column.
#include <stdio.h>
#include <stdlib.h>
typedef struct pair {
int value, column;
} Pair;
int cmp(const void *a, const void *b){
Pair *pa = (Pair *)a;
Pair *pb = (Pair *)b;
return pa->value - pb->value;
}
int main(void){
int data[8] = {0, 3, 1, 5, 1, 2, 3, 4};
Pair data_pair[8];
int i;
for(i=0;i<8;++i){
data_pair[i].value = data[i];
data_pair[i].column = i;
}
qsort(data_pair, 8, sizeof(Pair), cmp);
for(i=0;i<3;++i)
printf("value = %d, column = %d\n", data_pair[i].value, data_pair[i].column);
return 0;
}
/* result
value = 0, column = 0
value = 1, column = 2
value = 1, column = 4
*/
#include <stdio.h>
#include <string.h>
#define SIZE 8
void delrow(int a[SIZE][SIZE], int row){
if(row < SIZE - 1)
memmove(&a[row], &a[row+1], (SIZE*SIZE - SIZE*(row+1))*sizeof(int));
};
void delcol(int a[SIZE][SIZE], int col){
int r;
if(col < SIZE - 1){
for(r=0;r<SIZE;++r){
memmove(&a[r][col], &a[r][col+1], (SIZE - (col+1))*sizeof(int));
}
}
}
int main(void){
int piezas[8][8] = {
0, 2, 2, 5, 3, 2, 1, 1,
0, 4, 5, 2, 4, 3, 0, 0,
0, 4, 2, 2, 1, 2, 3, 2,
0, 3, 1, 5, 1, 2, 3, 4,
2, 5, 6, 5, 3, 1, 2, 7,
8, 2, 0, 0, 0, 2, 1, 1,
1, 2, 2, 1, 1, 6, 3, 4,
0, 1, 3, 2, 0, 0, 0, 0,
};
//test
int row = 8, col = 8;
int r,c;
delrow(piezas, 3);
row -= 1;
for(r=0;r<row;++r){
for(c=0;c<col;++c)
printf("%2d", piezas[r][c]);
printf("\n");
}
printf("\n");
delcol(piezas, 1);
col -= 1;
for(r=0;r<row;++r){
for(c=0;c<col;++c)
printf("%2d", piezas[r][c]);
printf("\n");
}
return 0;
}
/* result
0 2 2 5 3 2 1 1
0 4 5 2 4 3 0 0
0 4 2 2 1 2 3 2
2 5 6 5 3 1 2 7
8 2 0 0 0 2 1 1
1 2 2 1 1 6 3 4
0 1 3 2 0 0 0 0
0 2 5 3 2 1 1
0 5 2 4 3 0 0
0 2 2 1 2 3 2
2 6 5 3 1 2 7
8 0 0 0 2 1 1
1 2 1 1 6 3 4
0 3 2 0 0 0 0
*/
Below is extract to get a nth smallest element from a selected row -Your first requirement before removing a row and column.
Copy the row
Sort the copied row (save index too while sorting)
Sorted index represents position of value in sorted order
pick 0 th or 1st or nth min indexing the sorted index.
------------ Very Draft code ---- try optimize -------
#include <stdio.h>
#include<memory.h>
void sortIndex(int *array, int *arrayIdx)
{
int i=0,j=0;
int temp=0;
int tempArr[4];
memcpy(tempArr, array, 4*sizeof(int));
for(i=0;i<4;i++)
{
printf("%d ",tempArr[i]);
}
printf("\n");
for(i=0;i<4;i++)
{
for(j=i+1;j<4;j++)
{
if(tempArr[i]>tempArr[j])
{
temp = arrayIdx[i];
arrayIdx[i]=arrayIdx[j];
arrayIdx[j]=temp;
temp = tempArr[i];
tempArr[i]=tempArr[j];
tempArr[j]=temp;
}
}
}
printf("Sorted array Index\n");
for(i=0;i<4;i++)
{
printf("%d ",arrayIdx[i]);
}
printf("\n");
printf("Sorted array Value\n");
for(i=0;i<4;i++)
{
printf("%d ",array[arrayIdx[i]]);
}
printf("\n");
}
int main ()
{
int array[4][4] = {{4,3,2,1},{7,5,4,3},{6,5,4,4},{5,5,2,1}};
int sortedIdx[4] = {0,1,2,3};
int i,ii;
for(i=0;i<4;i++)
{
for(ii=0;ii<4;ii++)
printf("%d ",array[i][ii]);
printf("\n");
}
printf("(Note:Count from 0). Which Row : ");
scanf("%d",&i);
sortIndex(array[i],sortedIdx);
printf("\n");
printf("(Nth smallest value)Give a N value (0 to 3): ");
scanf("%d",&ii);
printf(" (%d) smallest value in row (%d) is (%d)\n",ii,i,array[i][sortedIdx[ii]]);
printf("Now call function to remove Row (%d) and column (%d)\n",i,sortedIdx[ii]);
return 0;
}

realloc() is screwing up my data... what's going on?

I'm writing a variable list implementation. In my insertion step, I check if the array's size is maxed out, and if so I double the maximum capacity and call realloc() to allocate me some new memory. Going from size 2 to 4, 4 to 8, and 8 to 16 works fine, but going from size 16 to 32 gives me some random zeroes in my array. Can anyone tell me what's going on here? I know I could avoid using realloc() by mallocing some new space, using memcpy and then freeing the old pointer... and perhaps there's no performance hit from doing that. But my intuition tells me that there is, and in any case I thought that's what realloc was there for. Can anyone tell me what's going on? The key function in this code is the append function.
#include <stdio.h>
#include <stdlib.h>
#include "problem5.h"
#define FAILURE -1
#define SUCCESS 0
ArrayList ArrayList_Init(int n, int (*append) (ArrayList, int), void (*print) (ArrayList), void (*insert) (ArrayList, int, int), void (*destroy) (ArrayList), int (*valueOf) (ArrayList, int))
{
ArrayList newArrayList = (ArrayList) malloc(sizeof(ArrayList_));
newArrayList->max_size = n;
newArrayList->current_size = 0;
newArrayList->data = malloc(n*sizeof(int));
newArrayList->append = append;
newArrayList->destroy = destroy;
newArrayList->print = print;
newArrayList->insert = insert;
newArrayList->valueOf = valueOf;
return newArrayList;
}// init a new list with capacity n
int append_(ArrayList list, int val)
{
//if the array is at maximum capacity
//double the capacity
//update max_size
//insert the value in the first open spot in the array (aka index current_size)
//increment current_size
if (list->current_size == list->max_size) {
list->max_size *= 2;
if (( list->data = realloc(list->data, list->max_size) ) == NULL)
return FAILURE;
}
list->data[list->current_size] = val;
list->current_size++;
return SUCCESS;
}
void print_(ArrayList list)
{
int i;
printf("List of size %d, max size %d. Contents:\n", list->current_size, list->max_size);
for (i=0; i<list->current_size; i++)
printf("%d, ", list->data[i]);
printf("\n");
}
void insert_(ArrayList list, int val, int index) {
}// insert val into index
void destroy_(ArrayList list)
{
//free list memory
}
int valueOf_(ArrayList list, int index)
{
//return value of specified element
return 0;
}
int main()
{
ArrayList list;
int stat, count = 0;
list = ArrayList_Init(2, append_, print_, insert_, destroy_, valueOf_); // init a new list with capacity 8
do {
printf("Appending %d\n", count);
stat = list->append(list, count) ; // add val to end of the list
list->print(list);
} while (stat == SUCCESS && ++count < 20);
return 0;
}
And here's the output of this:
Appending 0
List of size 1, max size 2. Contents:
0,
Appending 1
List of size 2, max size 2. Contents:
0, 1,
Appending 2
List of size 3, max size 4. Contents:
0, 1, 2,
Appending 3
List of size 4, max size 4. Contents:
0, 1, 2, 3,
Appending 4
List of size 5, max size 8. Contents:
0, 1, 2, 3, 4,
Appending 5
List of size 6, max size 8. Contents:
0, 1, 2, 3, 4, 5,
Appending 6
List of size 7, max size 8. Contents:
0, 1, 2, 3, 4, 5, 6,
Appending 7
List of size 8, max size 8. Contents:
0, 1, 2, 3, 4, 5, 6, 7,
Appending 8
List of size 9, max size 16. Contents:
0, 1, 2, 3, 4, 5, 6, 7, 8,
Appending 9
List of size 10, max size 16. Contents:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
Appending 10
List of size 11, max size 16. Contents:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
Appending 11
List of size 12, max size 16. Contents:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
Appending 12
List of size 13, max size 16. Contents:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
Appending 13
List of size 14, max size 16. Contents:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
Appending 14
List of size 15, max size 16. Contents:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
Appending 15
List of size 16, max size 16. Contents:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
Appending 16
List of size 17, max size 32. Contents:
0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,
Appending 17
List of size 18, max size 32. Contents:
0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 17,
Appending 18
List of size 19, max size 32. Contents:
0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 17, 18,
Appending 19
List of size 20, max size 32. Contents:
0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 17, 18, 19,
It is very bad to write so:
list->data = realloc(list->data, list->max_size)
You should use new variable and if memory was reallocated you write so:
List->data = temp;
It will protect you from memory leak.
And you forgot *sizeof(int)

Resources