I'm trying to learn C and am completing different challenges in order to learn faster. The code seems logical to me and should progress. However, I'm getting an invalid read of size four on line 29
I've tried to change the data type that gets parsed through, but it didn't seem to work.
#include <unistd.h>
typedef struct s_grid
{
int x;
int y;
} t_grid;
void set_point(t_grid *coord, int i, int j)
{
coord->x = i;
coord->y = j;
}
//check loccation of next zero
int where_is_zero(int **sudoku)
{
int x;
int y;
t_grid coord;
x = 0;
y = 0;
while (x < 9)
{
y = 0;
while (y < 9)
{
if (sudoku[x][y] == 0) //Here I'm getting the error.
{
set_point(&coord, x, y);
return (0);
}
x++;
}
y++;
}
return (1);
}
int solve_sudoku(int **grid)
{
int row;
int col;
int num;
t_grid coord;
if (where_is_zero(grid) == 1)
return (1);
row = coord.x;
col = coord.y;
//where_is_zero(grid);
num = 1;
while (num <= 9)
{
if (check_number(grid, row, col, num) == 1)
{
grid[row][col] = num;
if (solve_sudoku(grid) == 1)
return (1);
grid[row][col] = 0;
}
num++;
}
return (0);
}
void ft_putchar(char c)
{
write(1, &c, 1);
}
void ft_putstr(char *str)
{
while (*str != '\0')
{
ft_putchar(*str);
str++;
}
}
//my main function
int main(int argc, char **argv)
{
int board[9][9] ={ { 0, 9, 0, 0, 0, 0, 8, 5, 3 },
{ 0, 0, 0, 8, 0, 0, 0, 0, 4 },
{ 0, 0, 8, 2, 0, 3, 0, 6, 9 },
{ 5, 7, 4, 0, 0, 2, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 9, 0, 0, 6, 3, 7 },
{ 9, 4, 0, 1, 0, 8, 5, 0, 0 },
{ 7, 0, 0, 0, 0, 6, 0, 0, 0 },
{ 6, 8, 2, 0, 0, 0, 0, 9, 0 } };
solve_sudoku(board);
return (0);
}
I removed some code just to highlight where the problem is. It should find the next 0 in the table and set the coordinations to my structure.
The problem lies in how you have the loop set up. See my comments below:
while (x < 9)
{
y = 0;
while (y < 9)
{
if (sudoku[x][y] == 0) //Here I'm getting the error.
{
set_point(&coord, x, y);
return (0);
}
x++; // This increments the x index while you're inside the y loop
}
y++; // This increments the y index when you meant to increment the x
}
If you swap both lines, that should work fine and will resolve your out-of-bounds error.
What would also help you write this better is instead of using a while loop, use a for loop. If you haven't covered that topic yet, it's really straightforward:
for(int x = 0; x < 9 ; ++x)
{
for (int y = 0; y < 9; ++y)
{
if (sudoku[x][y] == 0) //Here you won't get the error anymore!
{
set_point(&coord, x, y);
return (0);
}
}
}
What the for loop line means there is this: Start the loop by setting it to 0, at the end of an iteration, increment it. On the next iteration, check if x is still less than 9. If so, proceed with the next iteration.
Your problem is due to mixing types. In main() you declare:
int board[9][9] = { ....
You then pass:
solve_sudoku(board);
board has the type int (*)[9] (a pointer to array of int [9]). See C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3). Your solve_soduku expects a parameter of type int** (pointer to pointer to int).
int solve_sudoku(int **grid) { ...
The type are NOT compatible. (and your compiler should be screaming warnings at you)
board is a pointer to array of int [9], while grid is a pointer to pointer to int. You must make the types compatible. The easiest way is to change solve_sudoku to
int solve_sudoku(int (*grid)[9]) { ...
Otherwise you will need to declare board as int** and allocate and fill in main().
Related
I am trying to print the initials of My First Name "S S" using * pattern in C. However the patterns are printed one after the other. Is there any way to print the alphabets using * pattern one at the side of the other with a little space in between. I do not want to allot a very big box for both the alphabets. I want to code for individual alphabets and put them side by side with some space in between. My Code and out our is given below:
int k,l,i,j;
for(k=1;k<=7;k++){
for(l=1;l<=4;l++){
if(k==1 && l<=4){
printf("*");
}
else if(k>=2 && k<=3 && l==1){
printf("*");
}
else if(k==4 && l<=4){
printf("*");
}
else if(k>=5 && k<=6 && l==4){
printf("*");
}
else if(k==7 && l<=4){
printf("*");
}
else{
printf(" ");
}
}
printf("\n");
}
for(i=1;i<=7;i++){
for(j=1;j<=4;j++){
if(i==1 && j<=4){
printf("*");
}
else if(i>=2 && i<=3 && j==1){
printf("*");
}
else if(i==4 && j<=4){
printf("*");
}
else if(i>=5 && i<=6 && j==4){
printf("*");
}
else if(i==7 && j<=4){
printf("*");
}
else{
printf(" ");
}
}
printf("\n");
}
return 0;
}
Output:
****
*
*
****
*
*
****
****
*
*
****
*
*
****
However, I want my expected output to be:
**** ****
* *
* *
**** ****
* *
* *
**** ****
The most important thing when approaching problems like this is to decompose your code in smaller pieces, using functions and/or typedefs or structs to organize things. In your case, you can easily separate the "knowledge" of how to print stars and spaces for your letters from the main code (which knows which letters to print in which order) using functions. Refactoring you code that way, we get:
void S(int k, int l) {
if(k==1 && l<=4){
printf("*");
}
else if(k>=2 && k<=3 && l==1){
printf("*");
}
else if(k==4 && l<=4){
printf("*");
}
else if(k>=5 && k<=6 && l==4){
printf("*");
}
else if(k==7 && l<=4){
printf("*");
}
else{
printf(" ");
}
}
int main() {
int k,l,i,j;
for(k=1;k<=7;k++){
for(l=1;l<=4;l++){
S(k, l);
}
printf("\n");
}
for(i=1;i<=7;i++){
for(j=1;j<=4;j++){
S(i, j);
}
printf("\n");
}
return 0;
}
Now you can easily rewrite main to print the letters side by side
int main() {
int k,l,i,j;
for(k=1;k<=7;k++){
for(l=1;l<=4;l++){
S(k, l);
}
printf(" ");
for(j=1;j<=4;j++){
S(k, j);
}
printf("\n");
}
return 0;
}
You could also extend this by writing different letters in different patterns (though having a function for each letter is somewhat verbose -- better would be to store the pixels for all letters in a data structure and print it that way)
Use pattern matrix for every character you want to print. It'll make printing easier. You run through each letter of the string to print for every row in the pattern.
#include <stdio.h>
#include <string.h>
#define ROWMAX 7
#define COLMAX 5
#define CSPACE 1
#define PATTERN '#'
char cCube [26][ROWMAX][COLMAX] = {
{ {0, 1, 1, 1, 1}, // letter S
{1, 1, 0, 0, 1},
{1, 1, 0, 0, 0},
{0, 1, 1, 1, 0},
{0, 0, 0, 1, 1},
{1, 0, 0, 1, 1},
{1, 1, 1, 1, 0}
},
{ {0, 1, 1, 1, 0}, // letter O
{1, 1, 0, 1, 1},
{1, 0, 0, 0, 1},
{1, 0, 0, 0, 1},
{1, 0, 0, 0, 1},
{1, 1, 0, 1, 1},
{0, 1, 1, 1, 0}
},
{ {1, 1, 1, 1, 0}, // letter D
{1, 0, 0, 1, 1},
{1, 0, 0, 0, 1},
{1, 0, 0, 0, 1},
{1, 0, 0, 0, 1},
{1, 0, 0, 1, 1},
{1, 1, 1, 1, 0}
}, //so on for alphabets you want to use
};
int chIndex [256] = {0};
void print_pat_msg (const char* msg) {
int mlen = strlen (msg);
for (int ri = 0; ri < ROWMAX; ++ri) {
for (int mi = 0; mi < mlen; ++mi) {
int chi = chIndex[ (unsigned char) msg[mi]];
for (int ci = 0; ci < COLMAX; ++ci)
(cCube[chi][ri][ci]) ? putchar (PATTERN) : putchar (' ');
for (int spi = 0; spi++ < CSPACE;) putchar (' ');
}
putchar ('\n');
}
printf ("\n");
}
int main () {
// if patterns are indexed alphabetically below initialisation can be omitted
chIndex[ (unsigned char) 'S'] = 0;
chIndex[ (unsigned char) 'O'] = 1;
chIndex[ (unsigned char) 'D'] = 2;
char message [] = "ODDS";
print_pat_msg (message);
return 0;
}
This way you can design/customise the pattern for each letter with ease at one place. Code & pattern can be reused for other messages & names.
Printing here works somewhat like a dot-matrix printer, striping across putting out pattern-line of each letter in the string one at a time.
You can also replace 0/1 flags with pretty much any character to draw ASCII images. You just have to adjust the pattern array, which is easy to follow & change at will.
Come to think of it, this is how fonts work at pixel level, patterns.
My quickie solution:
#include <stdio.h>
static const unsigned char S[] = {0xF0, 0x80, 0x80, 0xF0, 0x10, 0x10, 0xF0};
int main(void) {
for(int i=0; i<sizeof(S); ++i)
{
for(int b=7;b; --b)
{
printf("%c", "* "[!(S[i] & (1<<b))]);
}
for(int b=7;b; --b)
{
printf("%c", "* "[!(S[i] & (1<<b))]);
}
printf("\n");
}
return 0;
}
Output:
Success #stdin #stdout 0s 5548KB
**** ****
* *
* *
**** ****
* *
* *
**** ****
I have a homework to implement Bellman Ford's algorithm and test it on some graphs. I implemented the algorithm, tested it on 2 of 3 graphs and it works. But on the third graph I have no output when calling the function.
Graph* temaTrecuta = createGraph(10, 12);
addOrientedEdge(temaTrecuta, 0, 0, 1, 5);
addOrientedEdge(temaTrecuta, 1, 1, 2, 3);
addOrientedEdge(temaTrecuta, 2, 2, 3, 5);
addOrientedEdge(temaTrecuta, 4, 3, 9, 5);
addOrientedEdge(temaTrecuta, 5, 1, 9, 1);
addOrientedEdge(temaTrecuta, 6, 3, 4, 1);
addOrientedEdge(temaTrecuta, 7, 4, 8, 5);
addOrientedEdge(temaTrecuta, 8, 8, 7, 1);
addOrientedEdge(temaTrecuta, 9, 7, 5, 1);
addOrientedEdge(temaTrecuta, 10, 7, 6, 3);
addOrientedEdge(temaTrecuta, 11, 6, 0, 1);
This part creates the graph and its edges. The createGraph function takes as parameters number of vertices and edges.
void addOrientedEdge(Graph* graph, int index, int source, int destination, int cost) {
graph->edge[index].src = source;
graph->edge[index].dest = destination;
graph->edge[index].cost = cost;
graph->matrix[source][destination] = cost;
}
This is the function that adds a new edge.
Below is my implementation for Bellman Ford's algorithm.
void bellmanFord(Graph* gr, int src) {
int* dist = (int*)malloc(sizeof(int) * gr->V);
int* path = (int*)malloc(sizeof(int) * gr->V);
if (!path || !dist) {
printf("Nu am putut aloca.\n");
exit(1);
}
for (int i = 0; i < gr->V; ++i) {
dist[i] = INT_MAX;
path[i] = 0;
}
path[src] = -1;
dist[src] = 0;
for (int i = 1; i <= gr->V - 1; ++i) {
for (int j = 0; j < gr->E; ++j) {
int m = gr->edge[j].src;
int n = gr->edge[j].dest;
int cost = gr->edge[j].cost;
if (dist[m] != INT_MAX && dist[m] + cost < dist[n]) {
dist[n] = dist[m] + cost;
path[n] = m;
}
}
}
for (int i = 0; i < gr->E; ++i) {
int m = gr->edge[i].src;
int n = gr->edge[i].dest;
int cost = gr->edge[i].cost;
if (dist[m] != INT_MAX && dist[m] + cost < dist[n]) {
printf("Exista un ciclu negativ.");
return;
}
}
printBellmanSol(dist, gr->V, path);
free(dist);
free(path);
}
Since nothing references edge index, as long as it is unique and sequental, you should consider auto-incrementing. In addition to edge index E, have a new edge capacity. That is the number that is passed to createGraph, and set the counter, E = 0, initially. You could write your addOrientedEdge with one less parameter; take the next edge index.
static void addOrientedEdge(struct Graph* graph, int source, int destination, int cost) {
const int index = graph->E;
assert(graph && graph->E < graph->E_capacity);
graph->edge[index].src = source;
graph->edge[index].dest = destination;
graph->edge[index].cost = cost;
graph->E++;
graph->matrix[source][destination] = cost;
}
This would free you from having to worry about the edge numbers.
There was an edge missing that was causing the problem. Thanks to #user3386109 for seeing it.
I wanted to make a function that checks if a value exists in a matrix or not by giving (the matrice + the value I want to check + the line) as parameters and I'm getting an error on the transtype from an integer to a pointer. Please I need a help as soon as possible, thank you:)
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
bool Search(int *Mat[4][4], int val, int numLigne) {
int i;
for (i = 0; i <= 4; ++i) {
if (Mat[numLigne][i] == val)
return 1;
else
return 0;
}
}
int main() {
int Mat[4][4] = {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 },
{ 13, 14, 15, 16 }
};
int p;
p = Search(Mat[4][4], 5, 1);
printf("The number is: %d", p);
return 0;
}
Plenty problems
int *Mat[4][4] it is the array of pointers to int. Not the pointer to array. You want int Mat[4][4] here
Search(Mat[4][4], you do not pass the pointer to the function only the integer value which is taken outside the array bounds. 2 UBs in one call. You want Search(Mat, here
for( i=0; i<=4; ++i ) it is wrong as indexes in your array are from 0 to 3, and you integrate to 4. You want for( i=0; i<4; ++i )
This code
for( i=0; i<=4; ++i )
{
if(Mat[numLigne][i] == val )
return 1;
else
return 0;
}
is equivalent to:
if(Mat[numLigne][0] == val )
return 1;
else
return 0;
You will stop on the index 0 as you return on both conditions.
I think you need to read the pointer and array chapters of your favourite C book. You need to read about iterations, ifs and functions.
There are multiple problems in your code:
the prototype for Search should be bool Search(int Mat[4][4], int value, int row); or simply bool Search(int Mat[][4], int value, int row);. as posted you declare Mat to be a matrix of pointers to int.
the loop for (i = 0; i <= 4; ++i) should stop when i == 4, hence the test should be i < 4.
if the value if not found in the first column, you immediately return 0 without testing the other columns.
passing the matrix to the function is written Search(Mat, 5, 1). As posted, you attempt to pass the value of a matrix element outside the matrix.
Search returns a boolean indicating if the row contains the value, but the column number is not returned. It would be better to return the column number and return -1 if the value is not found.
Here is a modified version:
#include <stdio.h>
int Search(int Mat[4][4], int val, int row) {
for (int i = 0; i < 4; ++i) {
if (Mat[row][i] == val)
return i;
}
return -1; // not found
}
int main() {
int Mat[4][4] = {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 },
{ 13, 14, 15, 16 }
};
int col = Search(Mat, 5, 1);
if (col >= 0)
printf("The value %d is at position Mat[%d][%d]\n", 5, 1, col);
else
printf("The value %d is not present in row %d of Mat\n", 5, 1);
return 0;
}
This question already has an answer here:
How do I get a function to modify any of the parameters?
(1 answer)
Closed 4 years ago.
I've searched for a fix to this issue but haven't been able to find an explanation. I have a two dimensional struct which has an integer variable within it.
typedef struct
{
int example;
} Example;
typedef struct
{
Example two_dimensional_array[5][5];
} Example_Outer;
I then set this variable to 0 for all fields using the following function and print the current values.
void initialise(Example_Outer example)
{
for(int i = 0; i < 5; i++){
for(int j = 0; j < 5; j++){
example.two_dimensional_array[i][j].example = 0;
}
}
print_example(example);
}
During this print, the values all appear as 0's like they should.
Output:
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
I then run a new function that utilises the exact same print code, and receive the following output:
0, 0, 0, 0, 9,
0, -394918304, 32551, -2138948520, 32764,
1, 0, 1, 0, 1775692253,
21904, -394860128, 32551, 0, 0,
1775692176, 21904, 1775691312, 21904, -2138948320,
print method:
void print_example(Example_Outer example)
{
for(int i = 0; i < 5; i++){
for(int j = 0; j < 5; j++){
printf("%d, ", example.two_dimensional_array[i][j].example);
}
printf("\n");
}
}
main method:
int main( int argc, const char* argv[] )
{
Example_Outer example;
initialise(example);
printf("---------------\n");
print_example(example);
}
Why do the variables not remain set to 0? What is causing this and how can I fix it? Thank you!
First, you can initialize your struct like bellow in a simple way :
Example_Outer example = { 0 };
Or in second way :
typedef struct
{
Example two_dimensional_array[5][5] = { 0 };
} Example_Outer;
Now in your code , you forgot about * in your void initialise(Example_Outer example) function, and in this case you just passing a copy of struct in function.
So you should use of struct's address as parameter to the function with pointer (*) :
void initialise(Example_Outer *example)
{
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
example->two_dimensional_array[i][j].example = 0;
}
}
print_example(*example);
}
Finally you can pass your struct's address as following : ( Test it online ) :
int main(int argc, const char* argv[])
{
Example_Outer example;
initialise(&example);
printf("---------------\n");
print_example(example);
}
I am a rookie, and I hope this question is not a naive one!
I have the following function, where I use elements of one array as indices of another. However, despite my making no changes to the former, I see that the elements are being modified. The code is as follows:
void convert_to_bitmap(int n_shapes, int sizex, int sizey,
int ll_x[n_shapes], int ll_y[n_shapes],
int ur_x[n_shapes], int ur_y[n_shapes],
int shapes_ll_bitmap[sizex][sizey],
int shapes_ur_bitmap[sizex][sizey] )
{
int i;
for (i = 0; i < n_shapes; i++)
{
printf("%d, %d, %d, %d check1\n", ll_x[i], ll_y[i], ur_x[i], ur_y[i]);
}
for (i = 0; i < n_shapes; i++)
{
shapes_ll_bitmap[ll_x[i]][ll_y[i]] = 1;
shapes_ur_bitmap[ur_x[i]][ur_y[i]] = 1;
printf("%d, %d, %d, %d check2\n", ll_x[i], ll_y[i], ur_x[i], ur_y[i]);
}
}
And, the output shows that the first array has changed when I do so. Is there some way to keep it immutable?
Output:
0, 0, 0, 7 check1
0, 9, 0, 15 check1
1, 0, 1, 7 check1
1, 9, 1, 15 check1
2, 13, 2, 15 check1
2, 17, 2, 24 check1
2, 26, 2, 32 check1
0, 0, 0, 7 check2
0, 9, 0, 15 check2
1, 0, 1, 7 check2
1, 9, 1, 15 check2
1, 13, 2, 15 check2
2, 1, 2, 1 check2
1, 26, 2, 32 check2
This is how I invoke the function in main():
convert_to_bitmap(n_shapes, sizex, sizey, ll_x, ll_y, ur_x, ur_y, shapes_ll_bitmap, shapes_ur_bitmap);
And the declaration and initialization of the matrices in int main() is as follows:
int ll_x[n_shapes];
int ll_y[n_shapes];
int ur_x[n_shapes];
int ur_y[n_shapes];
int sizex;
int sizey;
int shapes_ll_bitmap[sizex][sizey];
int shapes_ur_bitmap[sizex][sizey];
for (i=0; i < sizex; i++)
{
for (j = 0; j < sizey; j++)
{
shapes_ll_bitmap[i][j] = 0;
shapes_ur_bitmap[i][j] = 0;
}
printf("\n");
}
Thank you!
Edit:
Here's some self-contained code:
int main(void)
{
enum { MAX_SHAPES = 100000 };
struct Rectangle rect_array[MAX_SHAPES];
int n_shapes = read_shapes_rpt("shapes.rpt", MAX_SHAPES, rect_array);
int i, j;
float pitch_x = 0.044;
float pitch_y = 0.042;
float ll_x_flt[n_shapes];
float ll_y_flt[n_shapes];
float ur_x_flt[n_shapes];
float ur_y_flt[n_shapes];
int ll_x[n_shapes];
int ll_y[n_shapes];
int ur_x[n_shapes];
int ur_y[n_shapes];
int sizex;
int sizey;
int shapes_ll_bitmap[sizex][sizey];
int shapes_ur_bitmap[sizex][sizey];
for (i=0; i < sizex; i++)
{
for (j = 0; j < sizey; j++)
{
shapes_ll_bitmap[i][j] = 0;
shapes_ur_bitmap[i][j] = 0;
}
printf("\n");
}
if (n_shapes > 0)
{
transform_to_shape_bit_locations(n_shapes, rect_array, ll_x_flt, ll_y_flt, ur_x_flt, ur_y_flt, ll_x, ll_y, ur_x, ur_y, &pitch_x, &pitch_y, &sizex, &sizey);
convert_to_bitmap(n_shapes, sizex, sizey, ll_x, ll_y, ur_x, ur_y, shapes_ll_bitmap, shapes_ur_bitmap);
printf("%d\n%d\n%d\n", n_shapes, sizex, sizey);
/* Use the shapes that were read */
}
return 0;
}
My shapes.rpt file contained the following csv values:
1.408,529.237,1.43,529.523
1.408,529.597,1.43,529.883
1.452,529.237,1.474,529.523
1.452,529.597,1.474,529.883
1.496,529.777,1.518,529.883
1.496,529.957,1.518,530.243
1.496,530.317,1.518,530.564
Your variables sizex and sizey are left uninitialized. Which means that your matrices shapes_ll_bitmap and shapes_ur_bitmap have unpredictable size (the behavior is actually undefined).
Note that when you actually assign meaningful values to your your sizex and sizey later, it is already too late. The matrices are already declared with indeterminate sizes and that's final. Once the matrices are declared, any changes to the values of sizex and sizey will have no effect on the matrices.
Your matrices end up with some indeterminate size, which results in out-of-bounds access inside convert_to_bitmap function and destruction of unrelated memory values.