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;
}
Related
Could somebody help me with this piece of code.
I have no idea that what it does.
#include <stdio.h>
int main()
{
int arr[5],i;
int a = 1, n = 5;
for (i=0; i<5;a+= arr[i++]);
int d = a;
printf("%d",d);
}
technically this code has pointers. That is because arrays are pointers to the values that are stored in it(arr[0-5]). Every Element of the array points to a Adress anywhere in the memory.
int main()
{
int arr[10];
unsigned int x;
for(x = 0; x < 9; x++)
{
arr[x] = x;
printf("%d ", *(arr+x));
}
return 0;
}
in this code you can see that you can use an pointer notation to navigate trough an array.
now to your second question. the code that you gave us here is first initializing a array with 5 elements, a int named 'i', a int named 'a' with the value 1, and a int named 'n' that has the value 5.
then you go into a for loop that repeats 5 times. in the for loop you give a the value of the array[i]. but because the array is not filled with numbers it comes a number that is anywhere in the memory.
next you give the variable 'd' the value of 'a'. and at least you print 'd'.
I think that you want it so that you go into a loop and it prints the elements of the array.
int main()
{
int arr[5], i, a = 1, d;
for(i = 0; i < 5; i++)
arr[i] = i;
for(i = 0; i < 5; i++)
{
a = arr[i];
d = a;
printf("%d ", d);
}
return 1;
}
i think that is what you want.
Of note, we've not put anything of interest into arr, however notice the semicolon on the end of this line:
for (i=0; i<5;a+= arr[i++]);
That's a succinct (confusing?) way of saying
for (i=0; i<5; i++)
{
a += arr[i];
}
So a is summing up whatever is in arr.
I am writing a program where I take 2 one dimensional arrays and generate a matrix in its most simplified form Ax=b.
This part of the function takes in the arrays A and b. A is A[n*n] and b is b[n]. In this section I tried to combine the two arrays so it looks like an actual matrix.
This code works, however, if n were to be greater than 1023 it would cause a segmentation fault when calling the main function. I was wondering if there is a better way in doing this. When I tried to use the GDB debugger, it stoped at the line Y[i][j] = A[k]; so I think this is the problem that requires fixing
int linsolve ( int n, double A[], double b[], double x []) {
double Y[n][n+1]; //Creating multidimensional matrix
int k = 0;
// Turns the two one dimensional array into one multidimensional
for (int i=0; i < n; i++){ //iterating row
for (int j=0; j < n; j++){ // per column
Y[i][j] = A[k]; // adding from array A to Y
k++;
}
Y[i][n] = b[i]; // adding from Array b to Y
}
I assume you are using a Unix/Linux type system. First find out the stack size by typing
ulimit -s
This is the stack size in kilobytes. On my system it is 8Mb. If you have a 1200x1200 matrix, that will require
1200x1201x8 appx 10Mb
This is why the program segvs. You are creating 10Mb array on an 8Mb stack. The question is, does A or b live on the stack too? You may be getting a segv because the item you are passing through was created on the stack and is larger than the allocated stack.
To solve it, create the array on the heap as #shirish has suggested. An alternative to #shirish's technique would be
int linsolve ( int n, double A[], double b[], double x []) {
double **Y = new double *[n];
double *Ybody = new double[n * (n + 1)];
for (int i = 0; i < n; i++) {
Y[i] = &Ybody[i * (n + 1)];
}
// Turns the two one dimensional array into one multidimensional
int k = 0
for (int i=0; i < n; i++){
for (int j=0; j < n; j++){
Y[i][j] = A[k++];
}
Y[i][n] = b[i];
}
// Do something
// Free up Y before returning
delete [] Y;
delete [] Ybody;
}
// Assuming A has n * n elements
int linsolve ( int n, double A[], double b[], double x []) {
double **Y = new double *[n];
for (int i = 0; i < n; i++) {
Y[i] = new double[n + 1];
}
int k = 0;
// Turns the two one dimensional array into one multidimensional
for (int i=0; i < n; i++){ //iterating row
for (int j=0; j < n; j++){ // per column
Y[i][j] = A[k++]; // adding from array A to Y
}
Y[i][n] = b[i]; // adding from Array b to Y
}
// Do something
// Free up Y before returning
for(int i = 0; i < n; i++) {
delete [] Y[i];
}
delete [] Y;
//Return int here
}
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;
I was writing a code the other day and I found it rather strange, that int** and int[][] does not behave the same way. Can anyone point out the differences between them? Below is my sample code, which fails with a segmentation fault, if I pass constant size 2d array, while it does work fine when I pass a dinamically allocated 2d array.
I am confused mainly because ant int[] array works the same as int*.
#include<stdio.h>
#include<stdlib.h>
void sort_by_first_row(int **t, int n, int m)
{
int i, j;
for(i = m-1 ; i > 0 ; --i)
{
for(j = 0 ; j < i; ++j)
{
if(t[0][j] < t[0][j+1])
{
int k;
for(k = 0 ; k < n ;++k)
{
int swap;
swap = t[k][j];
t[k][j] = t[k][j+1];
t[k][j+1] = swap;
}
}
}
}
}
int main(void) {
int i, j;
/* Working version */
/*int **t;
t =(int**) malloc(3*sizeof(int*));
for(i = 0; i < 3; ++i)
{
t[i] = (int*) malloc(6*sizeof(int));
}*/
/*WRONG*/
int t[3][6];
t[0][0] = 121;
t[0][1] = 85;
t[0][2] = 54;
t[0][3] = 89;
t[0][4] = 879;
t[0][5] = 11;
for( i = 0; i < 6; ++i )
t[1][i] = i+1;
t[2][0] = 2;
t[2][1] = 4;
t[2][2] = 5;
t[2][3] = 3;
t[2][4] = 1;
t[2][5] = 6;
sort_by_first_row(t, 3, 6);
for(i = 0; i < 3; ++i)
{
for(j = 0; j < 6; ++j)
printf("%d ", t[i][j]);
printf("\n");
}
return 0;
}
So based on the below answers I realize, that a multidimensional array is stored continuously in a row major order. After some modification, the below code works:
#include<stdio.h>
#include<stdlib.h>
void sort_by_first_row(int *t, int n, int m)
{
int i, j;
for(i = m-1 ; i > 0 ; --i)
{
for(j = 0 ; j < i; ++j)
{
if(t[j] < t[j+1])
{
int k;
for(k = 0 ; k < n ;++k)
{
int swap;
swap = t[k*m + j];
t[k*m + j] = t[k*m + j+1];
t[k*m + j+1] = swap;
}
}
}
}
}
int main(void) {
int i, j;
/* Working version */
/*int **t;
t =(int**) malloc(3*sizeof(int*));
for(i = 0; i < 3; ++i)
{
t[i] = (int*) malloc(6*sizeof(int));
}*/
/*WRONG*/
int t[3][6];
t[0][0] = 121;
t[0][1] = 85;
t[0][2] = 54;
t[0][3] = 89;
t[0][4] = 879;
t[0][5] = 11;
for( i = 0; i < 6; ++i )
t[1][i] = i+1;
t[2][0] = 2;
t[2][1] = 4;
t[2][2] = 5;
t[2][3] = 3;
t[2][4] = 1;
t[2][5] = 6;
sort_by_first_row(t, 3, 6);
for(i = 0; i < 3; ++i)
{
for(j = 0; j < 6; ++j)
printf("%d ", t[i][j]);
printf("\n");
}
return 0;
}
My new question is this: How to modify the code, so that the procedure works with int[][] and int** also?
Realize that int **t makes t a pointer to a pointer, while int t[3][6] makes t an array of an array. In most cases, when an array is used in an expression, it will become the value of the address of its first member. So, for int t[3][6], when t is passed to a function, the function will actually be getting the value of &t[0], which has type pointer to an array (in this case, int (*)[6]).
The type of what is being pointed at is important for how the pointer behaves when indexed. When a pointer to an object is incremented by 5, it points to the 5th object following the current object. Thus, for int **t, t + 5 will point to the 5th pointer, while for int (*t)[M], t + 5 will point to the 5th array. That is, the result of t + 5 is the same as the result of &t[5].
In your case, you have implemented void sort_by_first_row(int **t, int n, int m), but you are passing it an incompatible pointer. That is, the type of &t[0] (which is what t will become in main) is not the same as what the function wants, a int **t. Thus, when the sorting function starts to use that address, it will think its indexing into pointers, when the underlying structure is an array of arrays.
int** is quite different from int[][]. int** is simply a pointer to a pointer and would appear like the following:
in reality, you can access the entire multidimensional array with simply int* pointing to the first element, and doing simple math from that.
Here is the result of the separate allocations (in your commented code):
However when you allocate a multidimensional array, all of the memory is contiguous, and therefore easy to do simple math to reach the desired element.
int t[3][6];
int *t = (int*) malloc((3 * 6) * sizeof(int)); // <-- similarly
This will result in a contiguous chunk of memory for all elements.
You certainly can use the separate allocations, however you will need to walk the memory differently.
Hope this helps.
int t[3][6] is very nearly the same thing as int t[18]. A single contiguous block of 18 integers is allocated in both cases. The variable t provides the address of the start of this block of integers, just like the one-dimensional case.
Contrast this with the case you have marked as "working", where t gives you the address of a block of 3 pointers, each of which points to a block of memory with 6 integers. It's a totally different animal.
The difference between t[3][6] and t[18] is that the compiler remembers the size of each dimension of the array, and automatically converts 2D indices into 1D offsets. For example, the compiler automatically converts t[1][2] into *(t + 1*6 + 2) (equivalent to t[8] if it were declared as a one-dimensional array).
When you pass a multi-dimensional array to a function, there are two ways to handle it. The first is to declare the function argument as an array with known dimension sizes. The second is to treat your array like a 1D array.
If you are going to declare the size of your array, you would declare your function like this:
void sort_by_first_row(int t[][6], int n)
or this
void sort_by_first_row(int t[3][6])
You either have to declare all array dimension sizes, or you can leave out the first size. In both cases, you access elements of t using t[i][j]; you've given the compiler enough information to do the offset math that converts from 2D notation to a 1D index offset.
If you treat it as a 1D array, you have to pass the array dimensions and then do the offset math yourself.
Here's a full working example, where f and f2 both generate the same output:
void f(int* t, int m, int n)
{
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
std::cout << t[i * n + j] << " ";
std::cout << std::endl;
}
void f2(int t[][6], int m)
{
for (int i = 0; i < m; i++)
for (int j = 0; j < 6; j++)
std::cout << t[i][j] << " ";
std::cout << std::endl;
}
int main()
{
int t[3][6];
int val = 1;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 6; j++)
{
t[i][j] = val;
val++;
}
}
f(&(t[0][0]), 3, 6);
f2(t, 3);
return 0;
}
One thing to note is the hack-ish way I had to pass t to f. It's been a while since I wrote in C/C++, but I remember being able to pass t directly. Maybe somebody can fill me in on why my current compiler won't let me.
A int ** is a pointer to a pointer to an int, and can be a pointer to an array of pointers to arrays of ints. A int [][] is a 2-dimensional array of ints. A two-dimensional array is exactly the same as a one-dimensional array in C in one respect: It is fundamentally a pointer to the first object. The only difference is the accessing, a two-dimensional array is accessed with two different strides simultaneously.
Long story short, a int[][] is closer to an int* than an int**.
I have a 2D dynamic array.
I enter a line of 0's after line which has a biggest number:
void InsertZero(int **a, int pos){
int i, j;
a = (int**)realloc(a, n * sizeof(*a));
a[n-1] = (int*)calloc(n, sizeof(**a));
d = 0;
for(i = n-1; i > pos; i--){
for(j = 0; j < n; j++){
a[i][j] = a[i-1][j];
printf("%d ", a[i][j]);
}
}
for(i = 0; i < n; i++){
a[pos][i] = 0;
}
}
If i make a size of array 3, 5, 7, 9, ... it works correctly. But if a number of lines is 2, 4, 6, ... , it is an access violation error, when i try to print my array:
void Print(void){
int i, j;
for(i = 0; i < (n-d); i++){
for(j = 0; j < n; j++){
printf("%d\t", arr[i][j]);
}
printf("\n");
}
}
code: http://codepad.org/JcUis6W4
Looking at this I cannot make sense of.... Look at comment 1, you have n set somewhere to realloc a block of memory which a is of type int ** - a double pointer, how are you calling this function? Secondly, comment 2, Why did you call calloc when the realloc on a double pointer was called previously...? Assume n has value of 5, then, realloc is called on double pointer a, meaning a[0][1]..a[4][1], now calloc is called thus a[4] has a new block of memory...
void InsertZero(int **a, int pos){
int i, j;
/* 1. */
a = (int**)realloc(a, n * sizeof(*a));
/* Bzzzzt....if realloc failed, a gets overwritten! */
/* 2. */
a[n-1] = (int*)calloc(n, sizeof(**a));
/* 3. */
d = 0;
/* 4. */
for(i = n-1; i > pos; i--){
for(j = 0; j < n; j++){
a[i][j] = a[i-1][j];
printf("%d ", a[i][j]);
}
}
for(i = 0; i < n; i++){
a[pos][i] = 0;
}
}
Comment 3, what is d used for - useless variable?
Comment 4, you are under the presumption that the block of memory has array subscripts [0][0] to [4][4] if n had a value of 5!
Can you clarify all this?
Edit: Looking at it again... it is likely that a got overwritten when the call to realloc failed! I recommend this section of code to counteract this
int **tmpA;
tmpA = (int**)realloc(a, n * sizeof(*a));
if (tmpA != NULL){
a = tmpA;
....
a[n-1] = (int*)calloc(n, sizeof(**a));
for(i = n-1; i > pos; i--){
....
}
for(i = 0; i < n; i++){
....
}
}
In your function InsertZero you have a local variable a. This local variable is initially set with a the address of a pointer to an integer (you probably wanted the address of a pointer to an array of integers, i.e. int ***a).
When you call realloc you are assigning your local copy of a a pointer to a block of memory, however once you have finished with your function it is entirely possible for your local copy of a to be pointing somewhere different to the rest of your program. You probably wanted to say *a = (int **)realloc(a, n * sizeof(int *));.
Dangerously, you're using n which isn't passed to your function. It appears you've made the assumption that n is going to be 1 bigger than the previous size of the array - otherwise your call to calloc is superfluous and you are just rotating the array letting the last element drop off as a memory leak.
Let's use a simpler example with no arrays, no dimensions. Let's say you wanted to create a function:
void make_me_a_pointer( int **mynumber ) {
*mynumber = (int *)malloc( sizeof(int) );
**mynumber = 7; /* assign the value 7 to my allocated memory */
}
int main( void ) {
int *demoint;
make_me_a_pointer( &demoint );
printf( "Magic num is %d\n", *demoint );
}
However in your case you merely assigned a = realloc... and thus never communicated the new address of a outside your function.