Double pointer addresses - c

I created and allocated a double pointer like this:
int **a;
a = (int**)malloc(10 * sizeof(int *));
for (int i = 0; i < 10; i++)
*(a+i) = (int *)malloc(10 * sizeof(int));
And then I initialized it for example like this:
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
**a = 1;
(*a)++;
}
a++;
}
My problem and question is how can I save the address'es of my double pointer?At this moment I lost them and can't use them anymore.

Don't use explicit pointer arithmetic and dereferencing when array subscripting will do:
int rows = 10, cols = 10
int **a;
// don't cast the return value of malloc
a = malloc(rows * sizeof(*a));
for (int i = 0; i < rows; i++)
a[i] = malloc(cols * sizeof(**a));
...
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
a[i][j] = 1;
}
}

Return a from a function, save it as a class member, it is just like any other variable. If you want to save the contents of the arrays then do that (but that is not what I could call saving a double pointer -- by the way the usual description is "pointer-to-pointer").

Related

How can I create a matrix in a void function and return as parameter C

I have to create a matrix but with the following requirements:
create a function for it
the matrix has to be dynamic allocated inside the function
the matrix has to be returned as a parameter of the function (function has to be void)
What I tried:
void createMatrix(int n,float** matrix)
{
matrix = (float**)malloc(n * sizeof(float*));
for (int i = 0; i < n; i++)
matrix[i] = (float*)malloc(n* sizeof(float));
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
matrix[i][j] = 0;
}
int main()
{
int n;
FILE* fis;
fis = fopen("fileIn.txt", "r");
if (!fis)
{
printf("File not opened");
return;
}
fscanf(fis, "%d", &n);
fclose(fis);
float** matrix;
createMatrix(n, &matrix);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
printf("%f ", matrix[i][j]);
printf("\n");
}
return;
}
If you're passing the address of a float ** to a function, the type of the parameter should be float ***. So in the function, change the parameter type to that and use *matrix wherever matrix was used.
void createMatrix(int n, float ***matrix)
{
*matrix = malloc(n * sizeof(float*));
for (int i = 0; i < n; i++)
(*matrix)[i] = malloc(n* sizeof(float));
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
(*matrix)[i][j] = 0;
}
Note that the casts have also been removed, as casting the return value of malloc is not necessary and can mask other errors in your code.
You also should add error checking after the calls to malloc.
If you are creating the matrix such a way
matrix = (float**)malloc(n * sizeof(float*));
for (int i = 0; i < n; i++)
matrix[i] = (float*)malloc(n* sizeof(float));
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
matrix[i][j] = 0;
and want to return the matrix through a parameter then the function should be declared like
void createMatrix( int n, float ***matrix )
{
*matrix = malloc( n * sizeof( float* ) );
for ( int i = 0; i < n; i++ )
( *matrix )[i] = malloc( n * sizeof( float ) );
for ( int i = 0; i < n; i++ )
{
for ( int j = 0; j < n; j++ )
{
( *matrix )[i][j] = 0;
}
}
}
That is if you are passing the pointer matrix declared in main like
float** matrix;
to the function by reference through a pointer to it
createMatrix(n, &matrix);
then the corresponding function parameter will have the type float ***.
You'll need to change createMatrix as follows:
void createMatrix(int n,float*** matrix)
{
*matrix = (float**)calloc(n,sizeof(float*));
for (int i = 0; i < n; i++)
*matrix[i] = (float*)calloc(n,sizeof(float));
}
In order for the caller to be able to see the matrix you create, you have to pass a pointer to it... yes, that is a pointer-to-a-pointer-to-a-pointer. And by using calloc instead of malloc, the initialization to zero is handled for you.
Some things to note:
Your function is creating a pointer-to-pointer look-up table, not a 2D array. Pointer-to-pointer look-up tables only make sense when we want individually-sized items, which is never the case in a mathematical, square-shaped matrix. All the pointer-to-pointer trick achieves is bloat, slow access and needless complexity. You gain absolutely no advantages from it. For details see Correctly allocating multi-dimensional arrays
This look-up table is assigned to the local variable matrix and not returned from the function, which is a bug and a memory leak.
We can easily fix these bugs and design mistakes if you can drop those requirements you listed. Then there's a much better standard C function for all of this called calloc.
Usage:
size_t fx = 5;
size_t fy = 3;
float (*fmat)[fy] = calloc( 1, sizeof(float[fx][fy]) );
...
free(fmat);
This is much faster than your function, it doesn't come with needless type-generic programming, it allocates a true 2D array in contiguous memory which gives data cache coherence and it sets all data items to zero.

C Language, dynamic 3d array

I have to create a dynamic and 3 dimensional integer-Array in C.
But I have to create the pointers separately and use malloc. I know how to create 2d Array with malloc but I get confused using the following method, and i couldn't really find other question similar to this.
2x2x2 Integer-Array
First step:
int *firstD;
firstD = (int) malloc(2*sizeof(int));
Second step:
int *secondD;
secondD = (int) malloc(2 * firstD * sizeof(int));
Third step:
int *thirdD;
thirdD = (int) malloc(2 * secondD * sizeof(int));
I think maybe I have to add pointers in the starting (int*) and increase it every stepp by one more pointer?
Allocate an array to store pointers to arrays of row pointers.
Allocate arrays to store row pointers.
Allocate arrays to store each rows.
#include <stdlib.h>
int main(void) {
int size1 = 2, size2 = 2, size3 = 2;
int*** array;
array = malloc(sizeof(int**) * size1); // 1
for (int i = 0; i < size1; i++) {
array[i] = malloc(sizeof(int*) * size2); // 2
for (int j = 0; j < size2; j++) {
array[i][j] = malloc(sizeof(int) * size3); // 3
}
}
// free arrays
for (int i = 0; i < size1; i++) {
for (int j = 0; j < size2; j++) {
free(array[i][j]);
}
free(array[i]);
}
free(array);
return 0;
}
I wrote type names explicitly in the above example, but I suggest using dereferencing to obtain size of elements to allocate is better to prevent causing typos.
#include <stdlib.h>
int main(void) {
int size1 = 2, size2 = 2, size3 = 2;
int*** array;
// allocate arrays
array = malloc(sizeof(*array) * size1); // 1
for (int i = 0; i < size1; i++) {
array[i] = malloc(sizeof(*array[i]) * size2); // 2
for (int j = 0; j < size2; j++) {
array[i][j] = malloc(sizeof(*array[i][j]) * size3); // 3
}
}
// free arrays
for (int i = 0; i < size1; i++) {
for (int j = 0; j < size2; j++) {
free(array[i][j]);
}
free(array[i]);
}
free(array);
return 0;
}
Onitted in the above examples to make them simple, but you should check results of malloc() to see if the allocations are successful.

Memory Read Exception when working with 3D-Array in C

Even though I looked through stackoverflow for this issue for a bit, I couldnt figure out how to solve my problem. I know this a very primitive problem and there are many solutions for similar problems but they didnt help to find a solution.
Its fairly simple:
I allocate a three-dimensional array dynamiclly and the I store the number 2 in each field.
But VS gives me an access-violation.
Here is my code:
#include <stdlib.h>
#include <stdio.h>
int main() {
int width = 512;
int height = 512;
int ***colors = (int ***)malloc(width * sizeof(int **));
for (int i = 0; i < height; ++i) {
colors[i] = (int **)malloc(height * sizeof(int *));
for (int j = 0; j < 3; ++j) {
colors[i][j] = (int *)malloc(3 * sizeof(int));
}
}
for (int x = 0; x < width; x++)
for (int y = 0; y < height; y++)
for (int z = 0; z < 3; z++)
colors[x][y][z] = 2; //Memory Access Violation happens here
free(colors);
return EXIT_SUCCESS;
}
You got confused with index range for for loops.
That is you are not properly allocating the memory thus you will end up accessing out of bound while using it.
for (int i = 0; i < height; ++i) {
colors[i] = (int **)malloc(height * sizeof(int *));
for (int j = 0; j < 3; ++j) {
colors[i][j] = (int *)malloc(3 * sizeof(int));
}
}
should be
for (int i = 0; i < width; ++i) {
colors[i] = (int **)malloc(height * sizeof(int *));
for (int j = 0; j < height; ++j) {
colors[i][j] = (int *)malloc(3 * sizeof(int));
}
}

C - How to adapt this code for a very large/dynamic array to a 2 dimensional array?

int main()
{
double *array;
long int n;
n=10000000;//10^7
array = (double *) malloc(n*sizeof(double));
return 0;
}
basically, I want to use this code for a really big aray into a 2 dimensional array, which will have dimensions [very large][4].
If you want a 2D array, then allocate a 2D array. It's that simple.
double (*pArr)[4] = malloc(10000000 * sizeof pArr[0]);
Notes:
do not cast the return value of malloc().
use sizeof pArr[0] instead of sizeof(TheDataType) for defensive programming reasons.
This seems working on Wandbox.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
double (* array)[4];
long int n;
int i, j;
n=10000000;//10^7
array = (double (*)[4]) malloc(n*sizeof(double[4]));
printf("%u\n",(unsigned int)sizeof(array[0]));
printf("%u\n",(unsigned int)sizeof(double[4]));
for (i = 0; i <n; i++) {
for (j = 0; j < 4; j++) array[i][j] = (double)i * j;
}
for (i = 0; i < 10; i++) {
for (j = 0; j < 4; j++) printf("%f ", array[i][j]);
putchar('\n');
}
for (i = n - 10; i < n; i++) {
for (j = 0; j < 4; j++) printf("%f ", array[i][j]);
putchar('\n');
}
free(array);
return 0;
}
int n = 100000;
double** array = malloc(sizeof(double*)*n);
for (int i = 0; i < n; ++i)
{
array[i] = malloc(4*sizeof(double));
}
Also note that we don't cast the malloc's result(Do I cast the result of malloc?).

Passing two-dimensional array via pointer

How do I pass the m matrix to foo()? if I am not allowed to change the code or the prototype of foo()?
void foo(float **pm)
{
int i,j;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
printf("%f\n", pm[i][j]);
}
int main ()
{
float m[4][4];
int i,j;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
m[i][j] = i+j;
foo(???m???);
}
If you insist on the above declaration of foo, i.e.
void foo(float **pm)
and on using a built-in 2D array, i.e.
float m[4][4];
then the only way to make your foo work with m is to create an extra "row index" array and pass it instead of m
...
float *m_rows[4] = { m[0], m[1], m[2], m[3] };
foo(m_rows);
There no way to pass m to foo directly. It is impossible. The parameter type float ** is hopelessly incompatible with the argument type float [4][4].
Also, since C99 the above can be expressed in a more compact fashion as
foo((float *[]) { m[0], m[1], m[2], m[3] });
P.S. If you look carefully, you'll that this is basically the same thing as what Carl Norum suggested in his answer. Except that Carl is malloc-ing the array memory, which is not absolutely necessary.
If you can't change foo(), you will need to change m. Declare it as float **m, and allocate the memory appropriately. Then call foo(). Something like:
float **m = malloc(4 * sizeof(float *));
int i, j;
for (i = 0; i < 4; i++)
{
m[i] = malloc(4 * sizeof(float));
for (j = 0; j < 4; j++)
{
m[i][j] = i + j;
}
}
Don't forget to free() afterwards!
You can't. m is not compatible with the argument to foo. You'd have to use a temporary array of pointers.
int main()
{
float m[4][4];
int i,j;
float *p[4];
p[0] = m[0];
p[1] = m[1];
p[2] = m[2];
p[3] = m[3];
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
m[i][j] = i+j;
foo(p);
If you have a compiler that supports C99, the current C standard, then you can do this:
foo((float *[]){ m[0], m[1], m[2], m[3] });
(Note that this is exactly the same as AndreyT's answer, except that it forgoes having to name the temporary array)
you dont need to do any changes in the main,but you function will work properly if you change the formal prototype of your function to (*pm)[4] or pm[][4] because **pm means pointer to pointer of integer while (*pm)[4] or pm[][4] means pointer to poiner of 4 integers .
m here is also a pointer to pointer of 4 integers and not pointer to pointer of integers and hence not compatible.
#include<stdio.h>
void foo(float (*pm)[4])
{
int i,j;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
printf("%f\n", pm[i][j]);
}
int main ()
{
float m[4][4];
int i,j;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
m[i][j] = i+j;
foo(m);
}
Does foo(m) not work?
void foo(float **pm) is the same as void foo(float *pm[]) which is not a two-dimensional array of floats. It is an array of float*. Now, those float* may themselves point to float arrays, but that's a separate matter.
typedef float Float4[4];
void foo(Float4 *pm)
{
int i,j;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
printf("%f\n", pm[i][j]);
}
main()
{
Float4 m[4];
int i,j;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
m[i][j] = i+j;
foo(m);
return 0;
}
Using C99 which supports run-time sized arrays, the following is a possible way to pass a 2-dim array:
void foo(void *pm, int row, int col)
{
float (*m)[col] = pm;
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++)
printf("%4.1f%s", m[i][j], (j == col-1)?"\n":" ");
}
int main()
{
float m[4][4];
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
m[i][j] = i+j;
foo(m, 4, 4);
return 0;
}

Resources