This code should multiply matrix A with matrix B and calculate matrix C.
matA 3x2, matB 2x3 therefore matC should be `3x3.
However, when I print matC, the 3rd row contains garbage values.
I don't know where the mistake is — if I do something wrong with the pointers or maybe the calculate part is wrong.
This is what I see when printing it.
x x 2489458943
x x 2489587641
x x 2489745734
Or something like that.
I don't know why sometimes it works.
I mean it prints the correct values, but most of the time this is what I see.
#include <stdio.h>
int main() {
int x = 0,y = 0, z = 0;
int i,j,k;
int **matA;
int **matB;
int **matC;
matA = (int**)malloc(sizeof(int)*3); // making the matrixes by malloc functions
matB = (int**)malloc(sizeof(int)*2);
matC = (int**)malloc(sizeof(int)*3);
for(i = 0; i < 3; i ++)
{
matA[i] = (int*)malloc(sizeof(int)*2); // matA 3x2
}
for(i = 0; i < 2; i++)
{
matB[i] = (int*)malloc(sizeof(int)*3); // matB 2x3
}
for(i = 0; i < 3; i++)
{
matC[i] = (int*)malloc(sizeof(int)*3); // the calculated mat 3x3
}
for(i = 0; i < 3; i++)
{
printf("please eneter line number: %i",i+1); //putting the values by scanf function in matA
printf(" seperated with ','\n");
scanf("%d,%d",&x,&y);
matA[i][0] = x;
matA[i][1] = y;
}
for(i = 0; i < 2; i++)
{
printf("please eneter line number: %i",i+1);// putting the values in matB
printf(" of the second mat seperated with ','");
scanf("%i,%i,%i", &x, &y, &z);
matB[i][0] = x;
matB[i][1] = y;
matB[i][2] = z;
}
for(i = 0; i < 3; i++) // multiple the matrixes by 3 loops
{
for(j = 0; j < 3; j++)
{
for(k = 0; k < 2; k++)
{
matC[j][i] += matA[j][k]*matB[k][i];
}
}
}
for(i = 0; i < 3; i ++)// just printing to check if the matrix correct
{
for(j = 0; j < 3; j++)
{
printf("%i ",(int**)matC[i][j]);
}
printf("\n");
}
return 0;
}
You're not allocating enough space in your matrixes:
matA = (int**)malloc(sizeof(int)*3);
matB = (int**)malloc(sizeof(int)*2);
matC = (int**)malloc(sizeof(int)*3);
You're allocating space for an array int but you need an array of int *. Most likely, pointers are larger than integers on your system which means your arrays aren't large enough to hold what you want and you run of the end of the array. Doing so invokes undefined behavior.
Allocate space for arrays of int *. Also, don't cast the return value of malloc:
matA = malloc(sizeof(int *)*3);
matB = malloc(sizeof(int *)*2);
matC = malloc(sizeof(int *)*3);
You're also adding to elements of matC without initializing them. You should set them to 0 before doing so:
matC[j][i] = 0;
for(k = 0; k < 2; k++)
{
matC[j][i] += matA[j][k]*matB[k][i];
}
You also don't need a cast here:
printf("%i ",(int**)matC[i][j]);
Since each matC[i][j] has type int and you're printing an int. This also invokes undefined behavior because the type of the expression doesn't match the type for the format specifier.
You never initialize matC and then use matC +=
The malloc function allocates size bytes and returns a pointer to the allocated memory. The memory is not initialized. Try calloc instead.
Also, you have wrong int** initialization, should allocate pointer size sizeof(int*), not just sizeof(int):
matA = (int**)calloc(3, sizeof(int*));
matB = (int**)calloc(2, sizeof(int*));
matC = (int**)calloc(3, sizeof(int*));
Related
I have a 2 dimensional array of pointers:
typedef struct Cell{
Position p;
unsigned int value;
} Cell;
typedef struct Position{
unsigned int x;
unsigned int y;
} Position;
int size = 4;
Cell ***cells = malloc(sizeof(Cell**) * size);
int i,j;
for(i = 0; i < size; i++){
cells[i] = malloc(sizeof(Cell*) * size);
for(j = 0; j < size; j++){
cells[i][j] = malloc(sizeof(Cell));
}
}
What I want to do now is fill this array with pointers to cells, and initialize these cells to contain the value 0 like this:
for(i = 0; i < size; i++){
for(j = 0; j < size; j++){
Position p = {i,j};
Cell c = {p, 0};
cells[i][j] = &c; //This doesn't work
}
}
As you can already tell, writing the address of c into the pointer cells[i][j] is less than ideal, since every pointer now points to the same address. However I don't know how to fill this array with pointers pointing to individual addresses.
I tried something like this:
cells[i][j]->value = 0;
which of course also doesn't work. Can anyone give me a hint on how I can solve my problem?
I'm not sure why you say cells[i][j]->value = 0; doesn't work, I believe it should.
This should work to set all the members.
Cell ***cells = malloc(sizeof(Cell**) * size);
for(i = 0; i < size; i++){
cells[i] = malloc(sizeof(Cell*) * size);
for(j = 0; j < size; j++){
cells[i][j] = malloc(sizeof(Cell));
cells[i][j]->p.x = i;
cells[i][j]->p.y = j;
cells[i][j]->value = 0;
}
}
Additional:
for(i = 0; i < size; i++){
for(j = 0; j < size; j++){
Position p = {i,j};
Cell c = {p, 0};
cells[i][j] = &c; //This doesn't work
}
// to this line, 'c' & 'p' will be freed since it was allocated on stack not heap.
// 'c' & 'p' will be freed when program gets out of 2nd for loop, so either you can
// use memcpy to copy 'c' into cells[i][j] or use malloc to allocate 'c' and 'p'
}
You've already gotten your answer but I see no obvious reason to do that many allocations unless sizeof(Cell) * size * size is large enough to make a single allocation fail (but allocating smaller parts doesn't). I suggest doing one allocation only which gives a few benefits. In no particular order:
Faster allocation in most cases.
Faster access to the elements that will be tightly packed and therefore be more cache friendly.
Easier memory management - there is only one pointer to check and free.
Less total memory allocated than when allocating memory for a lot of pointers.
Example 1 - Make cells a pointer to the first of size number of elements of Cell[size].
// one allocation:
Cell (*cells)[size] = malloc( size * sizeof *cells );
if(cells == NULL) exit(1); // check for allocation failure
for(int i = 0; i < size; i++){
for(int j = 0; j < size; j++){
cells[i][j].p.y = i;
cells[i][j].p.x = j;
cells[i][j].value = 0;
}
}
Example 2 - Make cells a pointer to a single Cell[size][size]:
// one allocation:
Cell (*cells)[size][size] = malloc( sizeof *cells );
if(cells == NULL) exit(1); // check for allocation failure
for(int i = 0; i < size; i++){
for(int j = 0; j < size; j++){
(*cells)[i][j].p.y = i;
(*cells)[i][j].p.x = j;
(*cells)[i][j].value = 0;
}
}
I'm trying to make a code which converts some decimal numbers to bits.
There are more simple ways to reach this result but I'm poking around and joking with memory in C.
int ** decimalToBits(int *number,int size){
int **bits = (int **)malloc(sizeof(*bits)*size), i = 0;
for (int j = 0; j < size; j++) {
int * temp = (int *)malloc(sizeof(int));
while (number[j] >= 1) {
temp[i++] = number[j] % 2;
number[j] /= 2;
realloc(temp, sizeof(int));
}
printf("\n");
bits[j] = (int *) malloc(sizeof(int)*i);
for (int k = i-1; k >= 0; k--){
bits[j][k] = temp[k];
printf("%d" ,bits[j][k]);
}
i = 0;
}
return bits;
}
I'm having some allocation problems, first of all I'm going to explain the idea:
I pass to the function multiple numbers, so for example:
int numbers[2] = {23,73};
decimalToBits(numbers,2);
Each converted number will be stored in **bits double pointer, so bits[0] will contain the number 23 converted, and bits[1] will contain 73 converted as well.
The problem shows up when I do bits[j] = (int *) malloc(sizeof(int)*i); call,
because this seems to let the temp pointer to be overwritten with some random numbers. In fact if I remove the bits[j] = (int *) malloc(sizeof(int)*i); and bits[j][k] = temp[k]; lines and I replace printf("%d" ,bits[j][k]); with printf("%d" ,temp[k]);
the code seems to have a good behavior, and it gives me the correct output:
10111
1001001
I also noticed that allocating the bits[j] = (int *) malloc(sizeof(int)*8); externally from the for (int j = 0; j < size; j++) loop let the code works. So why this allocation problem occurs when declared just like the above code and what's the best way to solve it?
I have the following 2D array:
int censusData[4][3] = {{87290, 77787, 55632},
{83020, 78373, 62314},
{95588, 87934, 705421},
{112456, 97657, 809767}};
I want to print values column-wise in that, after 3 passes of a loop, it would print:
87290 83020 95588 112456
77787 78373 87934 97657
55632 62314 705421 809767
Notice how it's the first element from each sub-array, then the 2nd, then the third..etc
I can easily access each subarray when going row-wise using this:
int* averageCityIncome(int size, int size_2, int arr[][size_2]){
int* t_arr = malloc(4 * sizeof(int));
for (int i = 0; i < size; i++){
int avg = 0;
for (int j = 0; j < size_2; j++){
avg += arr[i][j];
}
avg /= size_2;
t_arr[i] = avg;
}
return t_arr;
}
But now I'm trying to read column-wise as stated above and I so far have this:
int* averageIncome(int size, int size_2, int arr[][size_2]){
int* t_arr = malloc(4 * sizeof(int));
for (int i = 0; i < size_2; i++){
for (int j = 0; j < size; j++){
printf("%d\n", arr[i][j]);
}
printf("-----\n");
}
return t_arr;
}
But it doesn't seem to be working. I'm still pretty new to C, and it's difficult to wrap my mind around 2D arrays still. Any help would be greatly appreciated.
You simply need to swap i and j for the dimensions when addressing a certain element of the array in the caller.
int* averageIncome(int size, int size_2, int arr[][size_2]) {
int* t_arr = calloc(4, sizeof(int)); // calloc to initialize the array elements to 0.
if ( t_arr == NULL )
{
fputs("Error at memory allocation for t_arr!", stderr);
exit(1);
}
int avg = 0; // definition of avg placed outside of the loop.
for (int i = 0; i < size_2; i++) {
for (int j = 0; j < size; j++) {
printf("%d\n", arr[j][i]); // j swapped with i.
avg += arr[j][i]; // same here too.
}
printf("-----\n");
t_arr[i] = avg / size;
avg = 0;
}
return t_arr;
}
Example (Online):
#include <stdio.h>
#include <stdlib.h>
#define ROWS 4
#define COLS 3
int* averageIncome(int size, int size_2, int arr[][size_2]) {
int* t_arr = calloc(4, sizeof(int)); // calloc to initialize the array elements to 0.
int avg = 0; // definition of avg placed outside of the loop.
for (int i = 0; i < size_2; i++) {
for (int j = 0; j < size; j++) {
printf("%d\n", arr[j][i]); // j swapped with i.
avg += arr[j][i]; // same here too.
}
printf("-----\n");
t_arr[i] = avg / size;
avg = 0;
}
return t_arr;
}
int main (void)
{
int censusData[ROWS][COLS] = {
{87290, 77787, 55632},
{83020, 78373, 62314},
{95588, 87934, 705421},
{112456, 97657, 809767}
};
int* p = averageIncome(ROWS, COLS, censusData);
for ( int i = 0; i < COLS; i++ )
{
printf("Average Income of %d. column is: %d\n", i + 1, p[i]);
}
return 0;
}
Output:
87290
83020
95588
112456
-----
77787
78373
87934
97657
-----
55632
62314
705421
809767
-----
Average Income of 1. column is: 94588
Average Income of 2. column is: 85437
Average Income of 3. column is: 408283
Side notes:
Always check the returned pointer from a memory-management for a null pointer if the allocation failed.
I used calloc() instead of malloc() to initialize all elements of the dynamically allocated array to 0.
The definition of avg should be placed before the nested loops, not within. Reset avg to 0 at the end of the outer loop.
avg /= size_2; t_arr[i] = avg; should be avg /= size; t_arr[i] = avg;. Note the replacement of size_2 with size.
avg /= size; t_arr[i] = avg; can be simplified by t_arr[i] = avg / size;.
#include <stdio.h>
int censusData[4][3] = {{87290, 77787, 55632},
{83020, 78373, 62314},
{95588, 87934, 705421},
{112456, 97657, 809767}};
int main() {
int* t_arr = malloc(3 * sizeof(int));
for(int i=0;i<3;i++){
int avg = 0;
for(int j=0;j<4;j++){
//Keep the I fixed here now J is varying and its position of column
//So you are reading all column values for ith row.
avg+=censusData[j][i];
}
avg/=4;
t_arr[i] = avg;
}
for(int i=0;i<3;i++){
printf("%d,",t_arr[i]);
}
return 0;
}
You can loop over the columns first and then print the corresponding element of each row:
for (int col = 0; col < 3; ++col)
{
for (int row = 0; row < 4; ++row)
{
printf("%d\n", censusData[row][col]);
// Do other stuff here
}
printf("-----\n");
}
For each row, the colth element is printed. So for col = 0, censusData[0][0], censusData[1][0], censusData[2][0], censusData[3][0] will be printed.
In your code, you can just swap the positions of the two for loops to iterate over the columns first.
I'm trying to create a 3D array of ints initialized to zeros each of fixed size denoted as "dim".
For example, for dim=3, it will have 27 cells for ints.
I tried this:
int ***board;
int **rows;
int *tried;
board = calloc(dim,sizeof(int**));
rows = calloc(dim*dim, sizeof(int*));
tried = calloc(dim*dim*dim, sizeof(int));
int i;
int j;
int k;
for (i=0 ; i<dim ; i++) {
board[i] = rows + i*dim*dim;
for (j=0 ; j<dim ; j++) {
board[i][j] = tried + j*dim + i*dim*dim;
}
}
for (i=0 ; i<dim ; i++) {
for (j=0 ; j<dim ; j++) {
for (k=0 ; k<dim ; k++) {
board[i][j][k] = 0;
}
}
}
Trying to debug it, I found that it works until:
board[1][1][0] = 0
And then the program gets stuck and i just can't find the reason.
Can someone explain this please?
Thanks!
First about the error in your code. Compare this:
rows = calloc(dim*dim, sizeof(int*));
to this:
for (i=0 ; i<dim ; i++) {
board[i] = rows + i*dim*dim;
The entire size of the array allocated to rows is dim*dim elements. So, already in the second iteration of this loop, you access it out of bounds. You probably meant:
for (i=0 ; i<dim ; i++) {
board[i] = rows + i*dim;
As I already mentioned in the comment, this is not a 3D array. It mimics the usage in code by using pointers and you're using a kind-of clever trick here, so you only need 3 allocations in total. This might be a good idea under the following conditions:
your dim is variable at runtime, so you can't know it in advance, and
you have to write code for compilers that don't support VLAs1) (variable-length-arrays).
If one of this conditions is not true, it's much better to use a real 3D array. If the array doesn't have to live after leaving your function and the size isn't huge, just use a simple variable with automatic storage duration like
int board[3][3][3] = { 0 }; // possibly #define the dimension
or, for a variable dim, requiring a compiler supporting VLAs
int board[dim][dim][dim] = { 0 };
If on the other hand, the array will be huge and/or you need to return it from your function, you indeed have to allocate it dynamically. Then just use the following:
int (*board)[3][3] = calloc(3, sizeof *board); // static size
int (*board)[dim][dim] = calloc(dim, sizeof *board); // dynamic case, with VLA suppport
Also note that calloc() already sets your allocated memory to 0, so no need for looping all over it.
Side notes:
with sizeof, prefer the expression form, so instead of writing
int *a = calloc(5, sizeof(int));
better write
int *a = calloc(5, sizeof *a);
this avoids errors when you later change the type of a.
always check the return value of malloc() and friends -- they might return a null pointer (e.g. when you're running out of memory).
1) VLAs don't exist in the oldest standards C89/C90 -- they were introduced in C99 as a mandatory feature, but later made optional in C11. This allows C11 compilers to omit them, which might make sense when e.g. targeting embedded systems. In practice, you can safely assume a C11 compliant compiler supports them if it isn't special purpose.
I rewrote your code to show how allocation of a 3D array could look like. And as pointed out in the comments, there's no need to initialize the array to 0 since calloc does that for you. Had you used malloc the array would not have been initialized.
#include <stdlib.h>
#include <stdio.h>
#define dim (3u)
int main() {
int x;
int y;
int z;
int ***cube;
cube = calloc(dim, sizeof(int**));
for (z = 0; z < dim; z++) {
cube[z] = calloc(dim, sizeof(int*));
for (y = 0; y < dim; y++) {
cube[z][y] = calloc(dim, sizeof(int));
}
}
for (z = 0; z < dim; z++) {
for (y = 0; y < dim; y++) {
for (x = 0; x < dim; x++) {
cube[z][y][x] = z + y + x;
}
}
}
for (z = 0; z < dim; z++) {
for (y = 0; y < dim; y++) {
for (x = 0; x < dim; x++) {
printf("%d ", cube[z][y][x]);
}
printf("\n");
}
printf("\n");
}
return 0;
}
What you want to store in it is up to you, in my example I wrote the sum of the counter to each index.
Code below is Unlicense.
I will suggest something different. Just create a 1D array and set some boundaries to interpret it as 3D. I added some test cases for you to better visualize how it works. Do not forget to look at how easy 'calloc' call is. Here is the code:
#include <stdlib.h>
#include <stdio.h>
int getindex(int dim, int x, int y, int z) {
return z * dim * dim + y * dim + x;
}
void printarray(int* tdarray, int dim) {
printf("[\n");
for (int i = 0; i < dim; i++) {
printf("\t[\n");
for (int j = 0; j < dim; j++) {
printf("\t\t[");
for (int k = 0; k < dim; k++) {
if (k == 0) printf("%d", *(tdarray + getindex(dim, k, j, i)));
else printf(",\t %d", *(tdarray + getindex(dim, k, j, i)));
}
printf("]\n");
}
printf("\n\t]\n");
}
printf("]\n");
}
int main() {
int dim = 10;
size_t arraysize = sizeof (int) * dim * dim * dim;
int lookupindex = getindex(dim, 7, 5, 4); /* Numbers picked randomly */
int* tdarray = (int*) malloc(arraysize);
calloc(*tdarray, arraysize);
/* Below is test code and visualizations, all magic happens above.*/
if (*(tdarray + lookupindex) == 0) *(tdarray + lookupindex) = 7;
printf("tdarray[x:%d, y:%d, z:%d]:\t%d\n\n", 7, 5, 4, *(tdarray + lookupindex));
printarray(tdarray, dim);
printf("\n\n\n\n\n\n\n\n\n\n");
for (int i = 0; i < getindex(dim, 9, 9, 9) + 1; i++) *(tdarray + i) = i;
printarray(tdarray, dim);
free(tdarray);
}
I have been looking for a way to swap the names between two matrices in C. I have 2 square size x size matrices. I make some operation to the one of them, I put the result in a cell in the other matrix, then I swap their names and I repeat.
Below I am giving my code
int main(void){
int const size = 1000;
int const steps = 10;
float A[size][size], B[size][size];
int i,j,k;
int t = 0;
double sum = 0;
double sum1 = 0;
int const ed = size - 1;
for(i = 0; i < size; ++i){
for(j = 0; j < size; ++j){// initialize the matrices
A[i][j] = i+j;
B[i][j] = 0;
}
}
for(i = 0; i < size; ++i){//find the sum of the values in the first matrix
for(j = 0; j < size; ++j){
sum = sum + A[i][j];
}
}
printf("The total sum of the matrix 1 is %lf \n",sum);
for(k = 0; k < steps; ++k){//for each cell of the matrix A calculate the average of the values' of the cell and its surroundings and put it in the coresponding place in the matrix B and then copy matrix B to matrix A and repeat. There are special cases for the cells who are at the edges and the last or first row/column.
for(i = 0; i < size; ++i){
for(j = 0; j < size; ++j){
if(i==0){
if(j==0)
B[i][j]=(A[0][0]+A[0][1]+A[0][ed]+A[1][0]+A[ed][0])/5.0;
else if(j==ed)
B[i][j]=(A[0][ed]+A[0][0]+A[0][ed-1]+A[1][ed]+A[ed][ed])/5.0;
else
B[i][j]=(A[0][j]+A[0][j+1]+A[0][j-1]+A[1][j]+A[ed][j])/5.0;
}else if(i==ed){
if(j==0)
B[i][j]=(A[ed][0]+A[ed][1]+A[ed][ed]+A[0][0]+A[ed-1][0])/5.0;
else if(j==ed)
B[i][j]=(A[ed][ed]+A[ed][0]+A[ed][ed-1]+A[0][ed]+A[ed-1][ed])/5.0;
else
B[i][j]=(A[ed][j]+A[ed][j+1]+A[ed][j-1]+A[0][j]+A[ed-1][j])/5.0;
}else{
if(j==0)
B[i][j]=(A[i][0]+A[i][1]+A[i][ed]+A[i+1][0]+A[i-1][0])/5.0;
else if(j==ed)
B[i][j]=(A[i][ed]+A[i][0]+A[i][ed-1]+A[i+1][ed]+A[i-1][ed])/5.0;
else
B[i][j]=(A[i][j]+A[i][j+1]+A[i][j-1]+A[i+1][j]+A[i-1][j])/5.0;
}
}
}
sum1 = 0;
for(i = 0; i < size; ++i){
for(j = 0; j < size; ++j){
sum1 = sum1 + B[i][j];
}
}
t=t+1;
for(i = 0; i < size; ++i){
for(j = 0; j < size; ++j){
A[i][j] = B[i][j];
}
}
printf("%lf \n",sum1-sum);
}
printf("The total sum of the matrix 2 is %lf \n",sum1);
printf("Number of steps completed: %i \n",t);
printf("Number of steps failed to complete: %i \n", steps-t);
return 0;
}
I have used the method of copying each time the one matrix to the other, but this is not efficient.
I have a hint that I should use pointers but I can not figure it out. Any help will be much appreciated.
You can swap the values of any two variables of the same type by assigning the value of the first to a temporary variable then assigning the value of the second to the first, then assigning the value of the temporary variable to the second:
int a = 2, b = 3, tmp;
tmp = a;
a = b;
b = tmp;
In particular, it works exactly the same when the variables are of pointer type, so
/* The matrices */
double one[3][3], another[3][3];
/* pointers to the matrices */
double (*matrix1p)[3] = one;
double (*matrix2p)[3] = another;
double (*tmp)[3];
/* ... perform matrix operations using matrix1p and matrix2p ... */
/* swap labels (pointers): */
tmp = matrix1p;
matrix1p = matrix2p;
matrix2p = tmp;
/* ... perform more matrix operations using matrix1p and matrix2p ... */
Updated to clarify:
matrix1p is initially an alias for one, and matrix2p is initially an alias for another. After the swap, matrix1p is an alias for another, whereas matrix2p is an alias for one. Of course, you can perform such a swap as many times as you want. You cannot, however, swap one and another themselves, except via an element-by-element swap.
Note that this yields improved efficiency because pointers are quite small relative to the matrices themselves. You don't have to move the elements of the matrices, but only to change which matrix each pointer refers to.
Yes, you should definitely use pointers, for example:
void swap (int*** m1, int*** m2)
{
int** temp;
temp = *m1;
*m1 = *m2;
*m2 = temp;
}
And then invoke:
int m1[5][5] = 0;
int m2[5][5] = 0;
swap (&m1, &m2);