c Program crashing using 2d array comparing values - c

Hi im having problems with my c code it keeps crashing with no error and im not sure why. i am trying to find the value at a point inside a 2d array for example [1][1] and see what the value is there (only 1 or a 0) and then process the value depending on if its 1 or a 0 but the program keeps crashing with no error and im not sure why.please help
typedef struct gol{ // structure containing a square board
int **board; // pointer to a pointer
size_t size; //size_t = unnasigned value
}gol;
the struct is created in main using
struct gol *GAME;
GAME = create_gol(30);
using an if menu options if option is selected it will just call
next pattern function but it crashes
gol* create_gol(size_t size){
struct gol *Game_Of_Life;
Game_Of_Life = (struct gol*)malloc(sizeof(struct gol*)); //dynamically create the struct the ptr is pointing to **IMPORTANT
Gameboard = new int*[size];
for (int i = 0; i < size; ++i) {
Gameboard[i] = new int[size];
// each i-the pointer is now pointing to dynamic array (size 20) of actual int values
}
for (int i = 0; i < size; ++i) { // for each row
for (int j = 0; j < size; ++j) { // for each column
Gameboard[i][j] = 0;
}
}
Game_Of_Life->board=Gameboard;
Game_Of_Life->size=size;
return Game_Of_Life;
}
void next_pattern(gol* g)
{
for (int i = 0; i < 20; ++i) { // for each row
for (int j = 0; j < 20; ++j) { // for each column
int sum = neighbour_sum(g,i,j);
if (g->board[i][j]==1){
if (sum<2){
g->board[i][j]=0;
}
if (sum==3 || sum==2 ){
g->board[i][j]=1;
}
if (sum>3){
g->board[i][j]=0;
}
}
if (g->board[i][j]==0 && sum==3){
g->board[i][j]=1;
}
}
}
}
updates neighbour sum so it cant go out of bounds program still crashing
int neighbour_sum(gol* g, int i, int j)
{ int sum;
if ((g->board[(i-1+g->size)%g->size][j])==1){ // left
sum++;
}
if ((g->board[(i-1+g->size)%g->size][(j-1+g->size)%g->size])==1){//left up
sum++;
}
if ((g->board[i][(j-1+g->size)%g->size])==1){ //up
sum++;
}
if ((g->board[(i+1)%g->size][(j+1)%g->size])==1){ //right up
sum++;
}
if ((g->board[i][(j+1)%g->size])==1){ //right
sum++;
}
if ((g->board[(i+1)%g->size][(j+1)]%g->size)==1){//right bottom
sum++;
}
if ((g->board[i][(j+1)%g->size])==1){//bottom
sum++;
}
if ((g->board[(i-1+g->size)%g->size][(j+1)%g->size])==1){// bottom left
sum++;
}
return sum;
}

These lines
for (int i = 0; i < 20; ++i) { // for each row
for (int j = 0; j < 20; ++j) { // for each column
int sum = neighbour_sum(g,i,j);
means that you first call neighbour_sum with both i and j being zero.
Inside neighbour_sum you do:
if ((g->board[(i-1)][j])==1){ // left
^^^^
So since both i and j are zero, it is actually:
if ((g->board[-1][0])==1){ // left
^^^^
ups
So you access the array out of bounds. That may cause a crash. In any case it is illegal.
The general problem seems to be that you don't handle when the point is at the edge of the board.
edit after OP posted more code
This is wrong
Game_Of_Life = (struct gol*)malloc(sizeof(struct gol*));
^^^
do
Game_Of_Life = malloc(sizeof(struct gol));

I found the solution in the end there where a number of issues including i was looking for value outside of the array that was solved using
if ((g->board[(i-1+g->size)%g->size][j])==1){ // left
sum++;
}
i also was using c++ syntax instead of c syntax witch was resolved using the malloc function
Game_Of_Life = (struct gol*)malloc(sizeof(struct gol));
and the last issue causing the crashing still was the function neighbour sum was returning -2 because it wasn't initialized at 0 properly
int sum = 0;

Related

How to increment value in a struct matrix in c?

I've calloc'd a correlation matrix in a struct but am unable to increment/set values in that matrix. The struct is
typedef struct matrixStruct{
char** word;
int numberOfWords;
int** matrix;
} matrix;
This is how i've allocated the structure using calloc. I've used calloc because i'd like all the values in the matrix to be 0.
//Allocate rows of matrix
wordStore->matrix = calloc(2000,sizeof(int*));
//Allocate columns of matrix
for(int j = 0; j< 2000; j++)
{
wordStore->matrix[j] = calloc(2000,sizeof(int*));
}
Assume i have an array which has values of
int reference [] = {20,400,5,1899};
And this is how i'm trying to assign/increment values within the matrix, but it doesn't seem to work.
for(int k = 0; k<lenReference; k++)
{
for(int l = 0; l<lenReference;l++)
{
wordStore->matrix[k][l] += 1;
if(k == l){
wordStore->matrix[k][l] = 0;
}
}
}
This is the print loop that i'm using, and when i run the file it has an error that says "subscripted value is not an array, pointer, or vector", but i thought that this was the correct way to print a 2d array. What is the issue with this print?
for(int i = 0; i<2000; i++)
{
for (int j = 0; j<2000; j++)
{
printf("%08d ", words.matrix[i][j]);
}
printf("\n");
}
Any help would be much appreciated!

Undefined behavior with 2d array of struct C

I have a 2d array of structs that I am assigning strings to, here is my struct.
struct node {
char* value;
};
Here is my allocation (I am new to C so I am not sure if it is right) but there will always be 35 columns but there could be millions of rows.( I just had it at 3 for now for testing)
const int rows=3;
struct node ** arrayofnodes[rows][35];
for(int i=0; i<rows; i++) {
array[i] = malloc(test * sizeof array[0]);
for(int j=0; j<35; j++) array[i][j] = malloc(sizeof array[0][0]);
}
I then read in character by character from a csv file and have a temp string, and assign the value of the temp to the position I want by using this below.
//int row and count are defined in my while loop I have for counting commas(or what col I am on) then new lines for the rows
arrayofnodes[row][count]->value=strdup(temp);
printf("%s \n", arrayofnodes[row][count]->value);
printf("%d %d \n",row, count );
When I assign like the way above it seems to work. I added these print statements in to make sure it was assigning the right values.
For example above would print out something like
Red
0 0
And this is correct for that position.
But then after I do all of my assigning. I placed a print statement printf("%s \n", arrayofnodes[0][0]->value); to test if I can retrieve the 1st value as shown above which should be "Red".
In my terminal it outputs "#`??" or "#Pz?" or just any random output. I have tried this for a bunch of different positions besides 0,0, but they all get the same outcome. I guess I am just confused why the print statements work right after I assign them, but not at the end of my code when I call them later.
This is what it looks like you're trying to do. You will need to scan your csv file and compute the number of rows required, then populate the values however you want.
#include <stdio.h>
#include <stdlib.h>
struct node {
char* value;
};
int main() {
const int rows = 3; // you will need to compute this beforehand
const int columns = 35;
struct node** arrayofnodes = malloc(rows * sizeof(struct node*));
for (int i = 0; i < rows; ++i) {
arrayofnodes[i] = malloc(columns * sizeof(struct node));
}
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < columns; ++j) {
arrayofnodes[i][j].value = malloc(...);
strcpy(arrayofnodes[i][j].value, ...); // etc..
}
}
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < columns; ++j) {
free(arrayofnodes[i][j].value);
}
}
for (int i = 0; i < rows; ++i) {
free(arrayofnodes[i]);
}
free(arrayofnodes);
}
You can avoid overcomplicated allocation by using constant size inside the structure:
struct OneRow
{
char Value[35];
}
const int Rows=3;
OneRow *MyArray=NULL;
MyArray = (OneRow*) malloc (Rows*sizeof(OneRow));
You can now access each element (character) or a whole string as
MyArray[rownumber].Value[colnumber] = …
strcpy (MyArray[rownumber].Value, "I'm_shorter_than_35"); //34 chars max + null-term

Segmentation fault when accessing a 2D array in a structure whose pointer is returned from a function

I made a structure who has two members (int and int**), and I return the pointer to this structure from one function to main(). It is fine to access the int value in the structure. However, in main() I got Segmentation fault : 11 when I tried to access the element of the 2D array.
#include<stdio.h>
#include<stdlib.h>
typedef struct Square {
int value;
int **array;
} Square;
Square * generate();
int main(int argc, char *argv[]){
Square *sqrptr = generate();
printf("%d\n", sqrptr -> value);
/* It prints 1 */
/* Print out the 2D array */
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3 ; j++){
printf("%d ", *(*((sqrptr -> array) + i) + j));
}
printf("\n");
}
/* It gives segmentation fault */
return 0;
}
Square * generate(){
Square mySquare;
mySquare.value = 1;
mySquare.array = malloc(sizeof(int*) * 3);
/* Initialize the 2D array */
for (int i = 0; i < 3; i++){
*(mySquare.array + i) = malloc(sizeof(int) * 3);
for (int j = 0; j < 3; j++){
*(*(mySquare.array + i) + j) = 0;
}
}
/* Print out the 2D array */
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3l ; j++){
printf("%d ", *(*(mySquare.array + i) + j));
}
printf("\n");
}
/* I can see the complete 2D array here */
Square *sqrptr = &mySquare;
return sqrptr;
}
I have tried to generate the Square in main(), and use one pointer of the structure to access my 2D array. It works fine, so I guess I have missed something when I use a pointer returned from other functions. On the other hand, I can access the int value successfully, so I have no clues now.
Could someone please explain the underlying reason for this segmentation fault? Thanks!
You're returning a pointer to a local variable (&mySquare). Stack memory (where local variables reside) is when the function returns, so the resulting pointer is pointing to invalid memory. Allocate the struct, and return the pointer to heap memory:
Square *my_square = malloc(sizeof *my_square);
//do stuff
return my_square;
Or pass a pointer to a stack variable as argument:
Square * generate(Square *my_square)
{
//in case pointer wasn't provided, allocate
if (my_square == NULL) {
my_square = malloc(sizeof *my_square);
if (!my_square)
return NULL; // or exit or whatever
}
//initialize members. To initialize array to 3x3 zero matrix, you can use:
for (int i=0;i<3;++i)
my_square.array[i] = calloc(3, sizeof *my_square->array[i]);
//or even, if you change array member to type int*:
my_square.array = calloc(3*3, sizeof *my_square->array);
//at the end:
return my_square;
}
The latter is arguably the most flexible solution: if you want to work on stack, you call the function like so:
Square my_stack_square;
generate(&my_stack_square);
If you need to use heap memory, you can use:
Square *my_heap_square = generate(NULL);
As Jonathan Leffler pointed out, for a small struct such as this, returning by value isn't too much of a cost. Getting a struct on heap can be achieved in the same way as returning any other type:
Square generate( void )
{
Square my_square;
//initialize
return my_square;
}
//call like so:
Square sq = generate();
The idea here is that you'll use a local variable in the generate function to create a new square, initialize the fields, and then return it. Because in C everything is passed by value, this essentially means the function will assign the value of the local variable from the generate function to the caller's scoped sq variable. For small structs such as this, that's perfectly fine.
What's more, a common thing for compilers to do is to optimise these kinds of functions to the equivalent of the second example I posted: Essentially your function will be creating a new Sqaure object on the stack memory of the caller. This can happen, that's not to say it will. It depends on the optimization levels used when compiling, and on the size of the struct you're returning.
Basically, if you want to keep the code as close to what you have now, it's probably easiest to stick to the first version (returning a heap pointer).
The more flexible approach is the second one (as it allows you to use stack and heap, depending on how you call the function).
For now, using the third approach is perfectly fine: the compiler will most likely optimize the code to whatever makes most sense anyway.
Try this:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct Square {
int value;
int **array;
} Square;
Square * generate();
int main(int argc, char *argv[]){
Square *sqrptr = generate();
printf("%d\n", sqrptr -> value);
/* It prints 1 */
/* Print out the 2D array */
int i,j;
for (i = 0; i < 3; i++){
for (j = 0; j < 3 ; j++){
printf("%d ", *(*((sqrptr -> array) + i) + j));
}
printf("\n");
}
/* It gives segmentation fault */
return 0;
}
Square * generate(){
Square* mySquare = (Square*) malloc(sizeof(Square)); //c++ compiler
//Square* mySquare = (void*) malloc(sizeof(Square)); //c compiler
mySquare->value = 1;
mySquare->array = malloc(sizeof(int*) * 3);
/* Initialize the 2D array */
int i,j;
for (i = 0; i < 3; i++){
*(mySquare->array + i) = malloc(sizeof(int) * 3);
for (j = 0; j < 3; j++){
*(*(mySquare->array + i) + j) = 0;
}
}
/* Print out the 2D array */
for (i = 0; i < 3; i++){
for (j = 0; j < 3l ; j++){
printf("%d ", *(*(mySquare->array + i) + j));
}
printf("\n");
}
/* I can see the complete 2D array here */
return mySquare;
}

card game in c, shuffle linked list

I trying to shuffle a linked list in c.
My idea was to move the list into an array of card then to shuffle the array and then to put it all back in the linked list.
when I do build everything is ok but when id use the debugger the program stops and says "triggered a breakpoint" and i didn't to anything different .
Thanks for your help!
here is some of my code
typedef struct card
{
int rank;
int suit;
}card;
void shuffleDeckPlay(cardList *deck1, int size)
{
card *array = (card*)malloc(sizeof(card));
for (int i = 0; i < size ; i++)
{
array[i] = deck1->front->data;
array = realloc(array, sizeof(card));
Dequeue(deck1);
}
int i, j;
card temp;
for (i = 0; i < size; i++)
{
j = rand() % size;
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
for (int i = 0; i < size; i++)
{
Enqueue(array[i], deck1);
}
}
array is only large enough to store one card. Even after you realloc, you are only realloc-ing it to a size of one. Syntactically there is nothing wrong, however during runtime array[i] will go out of bounds and the debugger is picking it up.
The best solution would be to allocate the correct number immediately:
card * array = (card*)malloc(numCards*sizeof(card));
However if you want to re-allocate in the for loop then your for loop should look like this:
for (int i = 0; i < size; i++) {
array = (card*)realloc(array, (i+1)*sizeof(card));
array[i] = deck1->front->data;
Dequeue(deck1);
}

2 Dimensional Array sorting in c

Here is a segment of my (incomplete) code
int rows(int board[][9]){
int badUnits = 0, i = 0, n = 9, j, z = 0;
int (*temp)[9];
//Sort each row of 2d array
for (z; z < n; z++){
for (i; i < n; i++){
for (j = i; j < n; j++){
if (board[z][i] > board[z][j]){
temp = board[z][i];
board[z][i] = board[z][j];
board[z][j] = temp;
}
}
}
}
printf ("%d\n", temp[1][0]);
printf ("%d\n", temp[1][1]);
return badUnits;
}
The function takes a 9*9 array.
I get a segmentation fault when the print statements are executed.
I believe my sort code is correct because it is similar to what I use for 1d arrays and I think everything else is correctly assigned.
So the culprit would be my temp variable. I have gone through and tried to assign values to it, tried to change the type, and have taken into account that the 2d array decays into a pointer but is not actually a pointer.
The conclusion I am left with is that this is a dynamic allocation issue. Can someone please lend a hand and assist me in fixing this? I have exhausted my knowledge base and am stuck.
To clarify: I decided to print the temp variable because I thought it would lend some information. The main problem was that the swap was not working, and I was still left with an unsorted array when I originally attempted to print out the board[][]. I know that board is what I am SUPPOSED to be printing.
Thank you for any help!
You assign an int value to temp
temp = board[z][i]; // Temp now is a what ever value was at
// That location in the array e.g. 42
You then treat temp as if it was the address in memory of an integer array
temp[1][1] // treat temp as a pointer and find the integer
// 10 integers further along then temp.
Also sometime temp will not have been initialised (never assigned to) in this case your going to get unexpected behaviour depending on what the last value stored where temp is now (Lets call it a random number).
Did you mean to output the values in board?
printf ("%d\n", board[1][0]);
printf ("%d\n", board[1][1]);
One thing to notice is that the variable temp will only get assigned to if a swap occurs, if the sorting algorithm was correct that is still a situation that could occur with a input corresponding to a sorted board.
But more importantly, the variable temp is used as an int during the swap. Later that integer value is interpreted as a pointer in the expressions temp[1][0] and temp[1][1], which in all likelihoods is not a valid address. You may want to change temp to be declared as:
int temp;
And figure out exactly what you would like to print. If it is whatever one of the two swapped values was (for the last swapped pair in the loop), then you would print it as:
printf("%d", temp);
Else, you would have to add logic according to what you really want to do.
Note that a single pass of this algorithm would not perform a complete sort, but I guess that's one of the reason why you said the provided code was not complete.
Something like this?
#include <stdio.h>
#include <stdlib.h>
void printArray(int** arr, int w, int h) {
for (int i = 0; i < w; ++i) {
for (int j = 0; j < h; ++j) {
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
void sortArray(int** arr, int w, int h) {
for (int row = 0; row < h; ++row) {
for (int col = 0; col < w; ++col) {
for (int i = 0; i < w; ++i) {
if (arr[row][i] > arr[row][col]) {
int tmp = arr[row][col];
arr[row][col] = arr[row][i];
arr[row][i] = tmp;
}
}
}
}
}
int main() {
int w = 9, h = 9;
int** arr = (int**)malloc(sizeof(int*) * w);
for (int i = 0; i < w; ++i) {
arr[i] = (int*)malloc(sizeof(int) * h);
for (int j = 0; j < h; ++j) {
arr[i][j] = rand() % 10;
}
}
printf("Unsorted:\n");
printArray(arr, w, h);
sortArray(arr, w, h);
printf("Sorted:\n");
printArray(arr, w, h);
for (int j = 0; j < h; ++j) {
free(arr[j]);
}
free(arr);
return 0;
}

Resources