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);
}
Related
I'm sorry to ask help for a HackerRank problem here, I know it's not really the right place but nobody is answering me on HackerRank. Also, I'm new in C, so don't be to rude please.
Problem's description:
You are given n triangles, specifically, their sides a, b and c. Print them in the same style but sorted by their areas from the smallest one to the largest one. It is guaranteed that all the areas are different.
Link to the problem : https://www.hackerrank.com/challenges/small-triangles-large-triangles/problem
We can only edit the sort_by_area function.
First of all, I didn't calculate the triangles' area, I've just calculated the perimeter of each triangle, because the formula is simpler to read and to execute. Normally, that doesn't change anything for the result since a bigger perimeter means a bigger area. Tell me if I'm wrong.
The problem is that I have unexpected results: there's numbers on a line from my output that I really don't know from where they come. See:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct {
int a;
int b;
int c;
} triangle;
void sort_by_area(triangle *tr, int n) {
// Array for storing the perimeter.
int *size = malloc(100 * sizeof(*size));
// Adding perimeters in size array.
for (int i = 0; i < n; i++) {
size[i] = tr[i].a + tr[i].b + tr[i].c;
}
// Sort.
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (size[j] > size[j + 1]) {
// Sort in size array.
int temp = size[j];
size[j] = size[j + 1];
size[j + 1] = temp;
// Sort in tr array.
temp = tr[j].a;
tr[j].a = tr[j + 1].a;
tr[j + 1].a = temp;
temp = tr[j].b;
tr[j].b = tr[j + 1].b;
tr[j + 1].b = temp;
temp = tr[j].c;
tr[j].c = tr[j + 1].c;
tr[j + 1].c = temp;
}
}
}
}
int main() {
int n;
scanf("%d", &n);
triangle *tr = malloc(n * sizeof(triangle));
for (int i = 0; i < n; i++) {
scanf("%d%d%d", &tr[i].a, &tr[i].b, &tr[i].c);
}
sort_by_area(tr, n);
for (int i = 0; i < n; i++) {
printf("%d %d %d\n", tr[i].a, tr[i].b, tr[i].c);
}
return 0;
}
Input:
3
7 24 25
5 12 13
3 4 5
Output:
0 417 0 // Unexpected results on this line.
3 4 5
5 12 13
Expected output:
3 4 5
5 12 13
7 24 25
It seems that an error occurs from the 7 24 25 triangle, but for me, my code seems to be good.... Can you help to find out what's wrong ? I really want to understand before going to another problem.
The assumption that a greater parameter implies a greater area is incorrect. Why? Imagine an isosceles triangle with a base of 1000 units and a height of 1e-9 units. The area is minuscule, compared to an equilateral triangle with unit length whereas the former has a huge perimeter (~2000 units) compared to the latter (3 units). That's just an (extreme) example to convey the flaw in your assumption.
I'd suggest you roll up your own area function. It's even mentioned on the problem page to use Heron's formula. Since it's just to be used in the comparison, then we don't need the exact area but an indicative area. So something like
double area(triangle const* tr) {
if(tr) {
double semiPerimeter = (tr->a + tr->b + tr->c)/2.0;
return semiPerimeter* (semiPerimeter - tr->a) * (semiPerimeter - tr->b) * (semiPerimeter - tr->c);
} else {
return 0;
}
}
Where we don't really need to calculate the square root since we just need to compare the areas across triangles and comparing the square of areas across triangles should be fine.
After this, it's just a matter of plugging this into whatever you did, after correcting the inner j loop to run only till n-1 (as the other answer has also explained)
void sort_by_area(triangle* tr, int n) {
/**
* Sort an array a of the length n
*/
double areaArr[n];
for(size_t i = 0; i < n; ++i) {
areaArr[i] = area(&tr[i]);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - 1; j++) {
if (areaArr[j] > areaArr[j + 1]) {
// Sort in area array.
int temp = areaArr[j];
areaArr[j] = areaArr[j + 1];
areaArr[j + 1] = temp;
// Sort in tr array.
triangle tmp = tr[j];
tr[j] = tr[j + 1];
tr[j + 1] = tmp;
}
}
}
}
You could directly use qsort too here since the problem doesn't prohibit using standard functions, something like:
int qsortCompare(void const* a, void const* b) {
triangle const* trA = a;
triangle const* trB = b;
if(trA && trB) {
double areaA = area(trA);
double areaB = area(trB);
return (areaA < areaB) ? -1 :
((areaA > areaB)? 1: 0);
}
return 0;
}
void sort_by_area(triangle* tr, int n) {
qsort(tr, n, sizeof(triangle), &qsortCompare);
}
Also, don't be restricted to add functions in the problem solution. The actual driver code only calls sort_by_area() but you can write other functions in the solution and call them from sort_by_area().
The inner loop does not need to run till n, only till n-1
for (int j = 0; j < n - 1; j++)
Because when j == n, then you are comparing with random junk outside of your respective arrays by accessing size[j+1] and tr[j+1].
Also, when swapping, you don't need to copy the structure members one-by-one. You can simply do:
// Sort in tr array.
triangle tmp = tr[j];
tr[j] = tr[j + 1];
tr[j + 1] = tmp;
Edit: As #CiaPan pointed out:
You have a memory leak. You need to call free() after you are done with using the malloc'd memory.
You are not allocating the right amount of memory. If you are passed more than 100 triangles, your code might behave weirdly or randomly crash.
int *size = malloc(n* sizeof(*size));
Full code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct {
int a;
int b;
int c;
} triangle;
void sort_by_area(triangle *tr, int n) {
// Array for storing the perimeter.
int *size = malloc(n* sizeof(*size));
// Adding perimeters in size array.
for (int i = 0; i < n; i++) {
size[i] = tr[i].a + tr[i].b + tr[i].c;
}
// Sort.
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - 1; j++) {
if (size[j] > size[j + 1]) {
// Sort in size array.
int temp = size[j];
size[j] = size[j + 1];
size[j + 1] = temp;
// Sort in tr array.
triangle tmp = tr[j];
tr[j] = tr[j + 1];
tr[j + 1] = tmp;
}
}
}
}
int main() {
int n;
scanf("%d", &n);
triangle *tr = malloc(n * sizeof(triangle));
for (int i = 0; i < n; i++) {
scanf("%d%d%d", &tr[i].a, &tr[i].b, &tr[i].c);
}
sort_by_area(tr, n);
for (int i = 0; i < n; i++) {
printf("%d %d %d\n", tr[i].a, tr[i].b, tr[i].c);
}
return 0;
}
I have a variable string, that I need to slice into smaller strings, the main string should be treated as a bidimensional array with a certain width and height MxM, and the smaller strings should be cut in blocks of NxN size. So for example, if I have the following string, char source[17] = "ABCDEFGHIJKLMNS0" and his bidimensional size is 4x4, and the size of the smaller blocks are 2x2, the smaller blocks should be ABEF, CDGH, IJMN, KLSO.
In other words, the string should be seeing as
ABCD
EFGH
IJKL
MNSO
and NxN should be cut from it, like:
AB
EF
Always with the constraint that these blocks should be linear arrays as the main string.
I have tried with 3 nested for, with the following code, but I didn't know how to calc the index of the main array in order to cut the blocks that way
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{
char pixelsSource[17] = "ABCDEFGHIJKLMNS0";
char pixelsTarget[4][5];
int Y = 0;
int X = 0;
for (int block = 0; block < 4; block++)
{
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
pixelsTarget[block][(i * 2) + j] = pixelsSource[(i * 2) + j];
printf("[%d][%d] = [%d] \n", block, (i * 2) + j, (i * 2));
}
}
}
for (int block = 0; block < 4; block++)
{
printf("%s\n", pixelsTarget[block]);
}
}
I broke this down into a more piece-by-piece way and generalized it for M & N. Here's the code, with inline comments:
#include <stdio.h>
#define M 4
#define N 2
int main(void)
{
// source data is an M * M string(plus null terminator)
char pixelsSource[M * M + 1] = "ABCDEFGHIJKLMNSO";
// destination is an array of N*N strings; there are M*M/N*N of them
char pixelsTarget[(M*M)/(N*N)][N*N + 1];
// iterate over the source array; blockX and blockY are the coordinate of the top-left corner
// of the sub-block to be extracted
for (int blockX = 0; blockX < M; blockX += N)
{
for (int blockY = 0; blockY < M; blockY += N)
{
int dstWord = blockX/N + blockY;
// for each letter in the sub-block, copy that letter over to the destination array
for (int y = 0; y < N; y++)
{
for (int x = 0; x < N; x++)
{
int dstIndex = y*N + x;
int srcIndex = (blockY + y)*M + blockX + x;
printf("[%d][%d] = [%d]\n", dstWord, dstIndex, srcIndex);
pixelsTarget[dstWord][dstIndex] = pixelsSource[srcIndex];
}
}
// null-terminate destination word
pixelsTarget[dstWord][N*N] = '\0';
}
}
// output
for (int block = 0; block < (M * M) / (N * N); block++)
{
printf("%s\n", pixelsTarget[block]);
}
}
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*));
I want to store a lower triangular matrix in memory, without storing all the zeros.
The way I have implemented it is by allocating space for i + 1 elements on the ith row.
However, I am new to dynamic memory allocation in C and something seems to be wrong with my first allocation.
int main ()
{
int i, j;
int **mat1;
int dim;
scanf("%d", &dim);
*mat1 = (int**) calloc(dim, sizeof(int*));
for(i = 0; i < dim; i++)
mat1[i] = (int*) calloc(i + 1, sizeof(int));
for(i = 0; i < dim; i++)
{
for(j = 0; j < i + 1; j++)
{
scanf("%d", &mat1[i][j]);
}
}
/* Print the matrix without the zeros*/
for(i = 0; i < dim; i++)
{
for(j = 0; j < (i + 1); j++)
{
printf("%d%c", mat1[i][j], j != (dim-1) ? ' ' : '\n');
}
}
return 0;
}
If you want to conserve space and the overhead of allocating every row of the matrix, you could implement a triangular matrix by using clever indexing of a single array.
A lower triangular matrix (including diagonals) has the following properties:
Dimension Matrix Elements/row Total elements
1 x . . . 1 1
2 x x . . 2 3
3 x x x . 3 6
4 x x x x 4 10
...
The total number of elements for a given dimension is:
size(d) = 1 + 2 + 3 + ... + d = (d+1)(d/2)
If you lay the rows out consecutively in a single array, you can use the formula above to calculate the offset of a given row and column (both zero-based) inside the matrix:
index(r,c) = size(r-1) + c
The formulas above are for the lower triangular matrix. You can access the upper matrix as if it was a lower matrix by simply reversing the indexes:
index((d-1)-r, (d-1)-c)
If you have concerns about changing the orientation of the array, you can devise a different offset calculation for the upper array, such as:
uindex(r,c) = size(d)-size(d-r) + c-r
Sample code:
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#define TRM_SIZE(dim) (((dim)*(dim+1))/2)
#define TRM_OFFSET(r,c) (TRM_SIZE((r)-1)+(c))
#define TRM_INDEX(m,r,c) ((r)<(c) ? 0 : (m)[TRM_OFFSET((r),(c))])
#define TRM_UINDEX(m,r,c,d) ((r)>(c)?0:(m)[TRM_SIZE(d)-TRM_SIZE((d)-(r))+(c)-(r)])
#define UMACRO 0
int main (void)
{
int i, j, k, dimension;
int *ml, *mu, *mr;
printf ("Enter dimension: ");
if (!scanf ("%2d", &dimension)) {
return 1;
}
ml = calloc (TRM_SIZE(dimension), sizeof *ml);
mu = calloc (TRM_SIZE(dimension), sizeof *mu);
mr = calloc (dimension*dimension, sizeof *mr);
if (!ml || !mu || !mr) {
free (ml);
free (mu);
free (mr);
return 2;
}
/* Initialization */
srand (time (0));
for (i = 0; i < TRM_SIZE(dimension); i++) {
ml[i] = 100.0*rand() / RAND_MAX;
mu[i] = 100.0*rand() / RAND_MAX;
}
/* Multiplication */
for (i = 0; i < dimension; i++) {
for (j = 0; j < dimension; j++) {
for (k = 0; k < dimension; k++) {
mr[i*dimension + j] +=
#if UMACRO
TRM_INDEX(ml, i, k) *
TRM_UINDEX(mu, k, j, dimension);
#else
TRM_INDEX(ml, i, k) *
TRM_INDEX(mu, dimension-1-k, dimension-1-j);
#endif
}
}
}
/* Output */
puts ("Lower array");
for (i = 0; i < dimension; i++) {
for (j = 0; j < dimension; j++) {
printf (" %2d", TRM_INDEX(ml, i, j));
}
putchar ('\n');
}
puts ("Upper array");
for (i = 0; i < dimension; i++) {
for (j = 0; j < dimension; j++) {
#if UMACRO
printf (" %2d", TRM_UINDEX(mu, i, j, dimension));
#else
printf (" %2d", TRM_INDEX(mu, dimension-1-i, dimension-1-j));
#endif
}
putchar ('\n');
}
puts ("Result");
for (i = 0; i < dimension; i++) {
for (j = 0; j < dimension; j++) {
printf (" %5d", mr[i*dimension + j]);
}
putchar ('\n');
}
free (mu);
free (ml);
free (mr);
return 0;
}
Note that this is a trivial example. You could extend it to wrap the matrix pointer inside a structure that also stores the type of the matrix (upper or lower triangular, or square) and the dimensions, and write access functions that operate appropriately depending on the type of matrix.
For any non-trivial use of matrices, you should probably use a third-party library that specializes in matrices.
mat1 = calloc(dim,sizeof(int*));
mat1 is a double pointer.You need to allocate memory for your array of pointers and later you need to allocate memory to each of your pointers individually.No need to cast calloc()
You are dereferencing mat1 at line 8 before it has even been set to point anywhere. You are allocating an array of pointers to int, but you are not assigning that to mat1 but to the dereference of mat1, which is uninitialized, we don't know what it points to.
So this line:
// ERROR: You are saying an unknown memory location should have the value of calloc.
*mat1 = (int**)calloc(dim,sizeof(int*));
Should change to:
// OK: Now you are assigning the allocation to the pointer variable.
mat1 = (int**)calloc(dim,sizeof(int*));
I'm trying to multiply two multidimensional arrays to form a matrix. I have this function. This should work in theory. However, I am just getting 0s and large/awkward numbers. Can someone help me with this?
int **matrix_mult( int **a, int **b, int nr1, int nc1, int nc2 )
{
int **c;
int i,j,k,l;
c = malloc(sizeof(int *)*nr1);
if (c == NULL){
printf("Insuff memm");
}
for(l=0;l<nr1;l++){
c[l] = malloc(sizeof(int)*nc1);
if (c[l] == NULL){
printf("Insuff memm");
}
}//for loop
for (i=0;i<nr1;i++){
for (j=0;j<nc2;j++){
for (k=0;k<nc1;k++){
c[i][j] = (a[i][k]) * (b[k][j]);
}
}
}
return( c );
}
Are you doing mathematical matrix multiplication? If so shouldn't it be:
for(i = 0; i < nr1; i++)
{
for(j = 0; j < nc1; j++)
{
c[i][k] = 0;
for(k = 0; k < nc2; k++)
{
c[i][k] += (a[i][j]) * (b[j][k]);
}
}
}
My full and final solution, tested to produce sensible results (I didn't actually do all the calculations myself manually to check them) and without any sensible niceties such as checking memory allocations work, is:
int **matrix_mult(int **a, int **b, int nr1, int nc1, int nc2)
{
int **c;
int i, j, k;
c = malloc(sizeof(int *) * nr1);
for (i = 0; i < nr1; i++)
{
c[i] = malloc(sizeof(int) * nc2);
for (k = 0; k < nc2; k++)
{
c[i][k] = 0;
for (j = 0; j < nc1; j++)
{
c[i][k] += (a[i][j]) * (b[j][k]);
}
}
}
return c;
}
There were a few typos in the core of the for loop in my original answer, mostly due to my being mislead by a different answer. These have been corrected for posterity.
If you change c[i][j] = (a[i][k]) * (b[k][j]); to c[i][j] += (a[i][k]) * (b[k][j]); in your code then it will work just fine provided that
nr1 is number of rows of matrix a
nc1 is the number of columns of the matrix a
nc2 is the number of columns of the matrix b
Just be sure that the matrix c is initiated with zeroes. You can just use calloc instead of malloc when allocating space, or memset the allocated array after a call to malloc.
One more tip is to avoid using the letter l when accessing array elements. when tired, you will have hard time noticing errors with l vs 1.