define pointer to pointer array - c

I want to use pointer to pointer to store a dynamic array data set but I don't know how to link them together. Does anyone know how to solve this problem?
How can I initialize the pointer to pointer array using dynamic array ? And how can I pick specific data set to do further program using pointer to pointer?
float *data;
float **dataIndex;
*dataIndex = (float**)malloc(number * sizeof(float*));
data = (float*) malloc(size * sizeof(float));
for(i = 0; i < size; i++){
scanf("%f", (data + i));
}

To dynamically allocate a 2D array, you will need to use a loop to initialize each pointer in the array.
float **arr;
size_t i, n;
if ((arr = malloc(n * sizeof(float *)) == NULL)
perror("malloc");
for (i = 0; i < n; ++i)
if ((arr[i] = malloc(sizeof (float))) == NULL)
perror("malloc");
Don't forget to free your memory.
while (--n >= 0)
free(arr[n]);
free(arr);
You need to be careful to free each subarray first, and then free the entire array.

That's not how allocate for pointer to pointers.
dataIndex = malloc(number * sizeof(float*));
for(i = 0; i < number; i++)
dataIndex[i] = malloc(size * sizeof(float));
Now if you want to populate data, you need to access it like a 2D array dataIndex[i][j].
for(i = 0; i < number; i++)
for(j = 0; j < size; j++)
scanf("%f", &dataIndex[i][j]);
Also remember to check errors and free memory.

Related

Problems when freeing a dynamically allocated 2d array in C

I am desperately trying to free a 2d int array and can't manage to do so.
I guess there's something wrong when i intialize the array?
Could you please help me out?
int rows = 2;
int cols = 3;
int *mfields = (int *) malloc(sizeof(int) * rows * cols);
int **matrix = (int **) malloc(sizeof(int *) * rows);
for (int i = 0; i < rows; i++) {
matrix[i] = mfields + i * cols;
for(int j=0; j<rows;j++) {
matrix[i][j] = (i+1)*(j+1);
}
}
for (int i = 0; i < rows; i++) {
free((matrix[i]));
}
free(matrix);
Thanks in advance,
Christian
Two chunks of memory are allocated:
int *mfields = (int *) malloc(sizeof(int) * rows * cols);
int **matrix = (int **) malloc(sizeof(int *) * rows);
and therefore two chunks of memory should be freed:
free(matrix);
free(mfields);
Freeing multiple chunks of memory, as this loop does:
for (int i = 0; i < rows; i++) {
free((matrix[i]));
is incorrect, as it passes addresses to free that were never returned from malloc.
Generally, it is not good to implement matrices as pointers-to-pointers. This prevents the processor from doing load prediction and impairs performance. If the C implementation(s) that will be used with the code support variable length arrays, then it is preferable to simply allocate one chunk of memory:
int (*matrix)[cols] = malloc(rows * sizeof *matrix);
If variable length array support is not available, then a program should allocate one chunk of memory and use manual calculations to address array elements. While this is may be more work for the programmer, it is better for performance:
int *matrix = malloc(rows * cols * sizeof *matrix);
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
matrix[i*cols + j] = (i+1) * (j+1);

Allocating memory for pointer struct which has pointer members

I am trying to read and print using struct pointer which has pointer members. So I am trying to read and print array of double struct pointers.
I tried the folowing but it is giving me error saying "Access violation writing location (somewhere in memory)"
How can I allocate memory dynamically for this?
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <stdio.h>
#include<string.h>
#include <stdlib.h>
typedef struct template{
char *name;
int *birthdate;
int *phoneNum;
} detailsOf;
void inputValue(detailsOf **person, int maxSize);
int main() {
detailsOf **person;
int maxSize = 0, menu = 0;
printf("Max:");
scanf("%d", &maxSize);
person = (detailsOf **)malloc(maxSize * sizeof(detailsOf **));
if (person == NULL) {
printf("Failed to allocate");
exit(0);
}
for (int i = 0; i < maxSize; i++) {
person[i]->name = (char *)calloc(21, sizeof(char ));
person[i]->birthdate = (int *)calloc(8, sizeof(int ));
person[i]->phoneNum = (int *)calloc(16, sizeof(int ));
}
inputValue(person, maxSize);
for (int i = 0; i < maxSize; i++) {
free(person[i]);
for (int j = 0; j < 21; j++) {
free(person[i]->name[j]);
}
for (int j = 0; j < 15; j++) {
free(person[i]->phoneNum[j]);
}
for (int j = 0; j < 8; j++) {
free(person[i]->birthdate[j]);
}
}
return 0;
}
void inputValue(detailsOf **person, int maxSize) {
for (int i = 0; i < maxSize; i++) {
printf("Name of %d", i + 1);
scanf("%s", person[i]->name);
for (int j = 0; j < 8; j++) {
printf("Birth %d:", i + 1);
scanf("%d", person[i]->birthdate[j]);
}
for (int k = 0; k < 8; k++) {
printf("Phone %d:", i + 1);
scanf("%d", person[i]->phoneNum[k]);
}
}
printf("SUCCESS\n");
}
person = (detailsOf **)malloc(maxSize * sizeof(detailsOf **));
should be
person = malloc(maxSize * sizeof(detailsOf *));
Then, this allocated memory to hold pointers to detailsOf but you never allocate memory for each detailsOf
for(int i=0; i<maxSize; i++)
{
person[i]=malloc(sizeof(detailsOf));
}
Also your freeing of memory should be
for (int i = 0; i < maxSize; i++)
{
free(person[i]->name);
free(person[i]->phoneNum);
free(person[i]->birthdate);
free(person[i]);
}
free(person);
Remember while freeing just match your free calls with malloc calls.
Rule is simple -- a pointer is uninitialized until it has had a valid address assigned to it, or memory has been allocated within which to store things and the starting address for the new block of memory assigned to it.
You allocate maxSize pointers for person, but then fail to allocate a struct for each person[i] before allocating for name, etc..
So you must allocate a struct, e.g. pointer[i] = malloc (sizeof *pointer[i]) before attempting to allocate person[i]->name = calloc(21, sizeof(char ));, ...
Also note, if you allocate based on the size of the derefernced pointer -- you will never get your allocation wrong, (your allocation of person is only correct as the result of happy-accident), instead, e.g.
person = malloc (maxSize * sizeof *person);
...
person[i] = malloc (sizeof *person[i]);
(and note a [] or -> counts as a dereference)
person[i]->name = calloc (21, sizeof *person[i]->name);
There is no need to cast the return of malloc, it is unnecessary. See: Do I cast the result of malloc?
person = (detailsOf **)malloc(maxSize * sizeof(detailsOf **));
This allocates an array of double pointers to type detailsOf with array size as maxSize.
sizeof(detailsOf**) is the size of an address, it does not give you the size of your user-defined datatype detailsOf.
Also, double pointer means, it is an address location which will store the address of another pointer which points to the memory location of detailsOf
/* if you want to use double pointer then */
detailsOf **dptr; // two dimensional array of detailsOf */
detailsOf *sptr; /* one dimentional array of detailsOf */
/* This allocates the memory for storing 3 detailsOf struct data */
sptr = malloc(3 * sizeof(detailsOf));
dptr = &sptr;
/* Now to access double ptr */
for (int i = 0; i < 3; ++i) {
dptr[0][i].birthdate = malloc(3 * sizeof(int));
}
for (int i = 0; i < 3; ++i) {
dptr[0][i].birthdate[0] = i;
dptr[0][i].birthdate[1] = i + 10;
dptr[0][i].birthdate[2] = i + 1990;
}
for (int i = 0; i < 3; ++i) {
printf("%d\\", dptr[0][i].birthdate[0]);
printf("%d\\", dptr[0][i].birthdate[1]);
printf("%d\n", dptr[0][i].birthdate[2]);
}
/* Not to free the double pointer,
* you have to free the inner pointer first then the outer pointers
* Easy to remember is to free in reverse order of your allocation order
*/
for (int i = 0; i < 3; ++i) {
free(dptr[0][i].birthdate);
free(dptr[0]);
/* free(dptr); this is not needed in this example because
* dptr is pointer to address of a local variable,
* but if it points to address of another array of detailOf*
* then this free is needed
*/
}
In your case, you have just an array of pointer and not an array of double pointers.

Dynamic Memory allocation for 2D Arrays in C Language

I am trying to solve a Leetcode problem in C.
https://leetcode.com/problems/pascals-triangle/description/
This is my solution to the problem.
I don't think there's an issue with the solution but dynamically allocating memory for a 2D array is getting very complex. Can someone please help me figure out how to correctly allocate memory dynamically to a 2D array. Updated the code based on BLUEPIXY suggestions, I still seem to be getting runtime error.
/**
* Return an array of arrays.
* The sizes of the arrays are returned as *columnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
int** generate(int numRows, int** columnSizes) {
int i=0,j=0,numColumns =2;
columnSizes = (int **)malloc(numRows * sizeof(int *));
for (i=0; i<numRows; i++)
columnSizes[i] = (int *)malloc( sizeof(int));
int **returnArray = (int **)malloc(numRows * sizeof(int *));
for (i=0; i<numRows; i++)
returnArray[i] = (int *)malloc((i+1) * sizeof(int));
returnArray[0][0] = 1;
*columnSizes =1;
for(i=1;i<numRows;i++)
{
for(j=0;j<numColumns;j++)
{
if(j==0 )
columnSizes[i][j] = returnArray[i-1][j];
else if(j==(numColumns-1))
columnSizes[i][j] = returnArray[i-1][j-1];
else
returnArray[i][j] = returnArray[i-1][j-1] + returnArray[i-1][j];
numColumns++;
}
*(columnSizes+i) = numColumns-1;
}
return returnArray;
}
Problems of new version
(1)
columnSizes = (int **)malloc(numRows * sizeof(int *));
for (i=0; i<numRows; i++)
columnSizes[i] = (int *)malloc( sizeof(int));
should be
*columnSizes = malloc(numRows * sizeof(int));
(※ it is not necessary to cast from void * in C).
(2)
*columnSizes =1;//type of `*columnSizes` is `int *`
should be
**columnSizes = 1;//meant columnSizes[0] = 1; at caller side (main)
(3)
columnSizes[i][j] = returnArray[i-1][j];
...
columnSizes[i][j] = returnArray[i-1][j-1];
should be
returnArray[i][j] = returnArray[i-1][j];
...
returnArray[i][j] = returnArray[i-1][j-1];
because this is typo.
(4)
numColumns++; move to after for(j=0;j<numColumns;j++){ }
(5)
*(columnSizes+i) = numColumns-1;
should be
*(*columnSizes+i) = numColumns-1;//For reasons similar to (2)
The whole fix code:
int** generate(int numRows, int** columnSizes) {
int i=0,j=0,numColumns =2;
*columnSizes = malloc(numRows * sizeof(int));
int **returnArray = (int **)malloc(numRows * sizeof(int *));
for (i=0; i<numRows; i++)
returnArray[i] = (int *)malloc((i+1) * sizeof(int));
returnArray[0][0] = 1;
**columnSizes = 1;
for(i=1;i<numRows;i++)
{
for(j=0;j<numColumns;j++)
{
if(j==0 )
returnArray[i][j] = returnArray[i-1][j];
else if(j==(numColumns-1))
returnArray[i][j] = returnArray[i-1][j-1];
else
returnArray[i][j] = returnArray[i-1][j-1] + returnArray[i-1][j];
}
numColumns++;
*(*columnSizes+i) = numColumns-1;
}
return returnArray;
}
Just do this
int *arr = (int *)malloc(r * c * sizeof(int));
and access the elements like this
int i, j, count = 0;
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
*(arr + i*c + j) = ++count;
OR
If you have the pointer to the pointer, then you get get some help from this code
int main()
{
int i,j;
int **p;
(p)=(int**)malloc(5*sizeof(int*));
for(i=0;i<5;i++)
*(p+i)=(int*)malloc(4*sizeof(int));
for(i=0;i<5;i++)
for(j=0;j<4;j++)
p[i][j]=2;
for(i=0;i<5;i++)
for(j=0;j<4;j++)
printf("%d",p[i][j]);
}
If all you have to do for your programming exercise is print out the results, why bother with any storage at all? Just use the solution here.
How to efficiently calculate a row in pascal's triangle?
Regarding multi-dimensional arrays and C, there is no native support for such a thing. So you have to build your own using one or more 1-D blocks of storage and tricks to index into that storage.
The simplest thing, which #tanuj-yadav suggested works fine for most 2-d arrays is just allocate a nXm-length block of storage and do very simple index arithmetic arr[i*c+j].
The other common approach is arrays of arrays (aka ragged arrays). Which is just like a list of lists, and are naively done with a malloc on each row (or column).

Dynamically allocating memory for array's elements

I have a two-dimension array of custom data type, say something like
struct element_t ** arr
How do I allocate space for this array's single elements (arr[i][j] ) using malloc()? Thanks in advance.
You can do the following :
struct element_t **arr;
arr = malloc(N * sizeof(*arr));
for (int i = 0; i < N; ++i) {
arr[i] = malloc(X * sizeof(*arr[i]));
}
Where N is the size of your double array and X the size of each array;
It depends how you want to allocate memory. If you want a contiguous chunk of memory then
arr = malloc(nrows * sizeof(*arr));
arr[0] = malloc(nrows * ncolumns * sizeof(struct element_t));
for(int i = 1; i < nrows; i++)
arr[i] = arr[0] + i * ncolumns;
For non contiguous
arr = malloc(nrows * sizeof(*arr));
for(int i = 0; i < nrows; i++)
arr[i] = malloc(ncolumns * sizeof(struct element_t));
For detailed explanation read How can I dynamically allocate a multidimensional array?

How do we allocate a 2-D array using One malloc statement

I have been asked in an interview how do i allocate a 2-D array and below was my solution to it.
#include <stdlib.h>
int **array;
array = malloc(nrows * sizeof(int *));
for(i = 0; i < nrows; i++)
{
array[i] = malloc(ncolumns * sizeof(int));
if(array[i] == NULL)
{
fprintf(stderr, "out of memory\n");
exit or return
}
}
I thought I had done a good job but then he asked me to do it using one malloc() statement not two. I don't have any idea how to achieve it.
Can anyone suggest me some idea to do it in single malloc()?
Just compute the total amount of memory needed for both nrows row-pointers, and the actual data, add it all up, and do a single call:
int **array = malloc(nrows * sizeof *array + (nrows * (ncolumns * sizeof **array));
If you think this looks too complex, you can split it up and make it a bit self-documenting by naming the different terms of the size expression:
int **array; /* Declare this first so we can use it with sizeof. */
const size_t row_pointers_bytes = nrows * sizeof *array;
const size_t row_elements_bytes = ncolumns * sizeof **array;
array = malloc(row_pointers_bytes + nrows * row_elements_bytes);
You then need to go through and initialize the row pointers so that each row's pointer points at the first element for that particular row:
size_t i;
int * const data = array + nrows;
for(i = 0; i < nrows; i++)
array[i] = data + i * ncolumns;
Note that the resulting structure is subtly different from what you get if you do e.g. int array[nrows][ncolumns], because we have explicit row pointers, meaning that for an array allocated like this, there's no real requirement that all rows have the same number of columns.
It also means that an access like array[2][3] does something distinct from a similar-looking access into an actual 2d array. In this case, the innermost access happens first, and array[2] reads out a pointer from the 3rd element in array. That pointer is then treatet as the base of a (column) array, into which we index to get the fourth element.
In contrast, for something like
int array2[4][3];
which is a "packed" proper 2d array taking up just 12 integers' worth of space, an access like array[3][2] simply breaks down to adding an offset to the base address to get at the element.
int **array = malloc (nrows * sizeof(int *) + (nrows * (ncolumns * sizeof(int)));
This works because in C, arrays are just all the elements one after another as a bunch of bytes. There is no metadata or anything. malloc() does not know whether it is allocating for use as chars, ints or lines in an array.
Then, you have to initialize:
int *offs = &array[nrows]; /* same as int *offs = array + nrows; */
for (i = 0; i < nrows; i++, offs += ncolumns) {
array[i] = offs;
}
Here's another approach.
If you know the number of columns at compile time, you can do something like this:
#define COLS ... // integer value > 0
...
size_t rows;
int (*arr)[COLS];
... // get number of rows
arr = malloc(sizeof *arr * rows);
if (arr)
{
size_t i, j;
for (i = 0; i < rows; i++)
for (j = 0; j < COLS; j++)
arr[i][j] = ...;
}
If you're working in C99, you can use a pointer to a VLA:
size_t rows, cols;
... // get rows and cols
int (*arr)[cols] = malloc(sizeof *arr * rows);
if (arr)
{
size_t i, j;
for (i = 0; i < rows; i++)
for (j = 0; j < cols; j++)
arr[i][j] = ...;
}
How do we allocate a 2-D array using One malloc statement (?)
No answers, so far, allocate memory for a true 2D array.
int **array is a pointer to pointer to int. array is not a pointer to a 2D array.
int a[2][3] is an example of a true 2D array or array 2 of array 3 of int
To allocate memory for a true 2D array, with C99, use malloc() and save to a pointer to a variable-length array (VLA)
// Simply allocate and initialize in one line of code
int (*c)[nrows][ncolumns] = malloc(sizeof *c);
if (c == NULL) {
fprintf(stderr, "out of memory\n");
return;
}
// Use c
(*c)[1][2] = rand();
...
free(c);
Without VLA support, if the dimensions are constants, code can use
#define NROW 4
#define NCOL 5
int (*d)[NROW][NCOL] = malloc(sizeof *d);
You should be able to do this with (bit ugly with all the casting though):
int** array;
size_t pitch, ptrs, i;
char* base;
pitch = rows * sizeof(int);
ptrs = sizeof(int*) * rows;
array = (int**)malloc((columns * pitch) + ptrs);
base = (char*)array + ptrs;
for(i = 0; i < rows; i++)
{
array[i] = (int*)(base + (pitch * i));
}
I'm not a fan of this "array of pointers to array" to solve the multi dimension array paradigm. Always favored a single dimension array, at access the element with array[ row * cols + col]? No problems encapsulating everything in a class, and implementing a 'at' method.
If you insist on accessing the members of the array with this notation: Matrix[i][j], you can do a little C++ magic. #John solution tries to do it this way, but he requires the number of column to be known at compile time. With some C++ and overriding the operator[], you can get this completely:
class Row
{
private:
int* _p;
public:
Row( int* p ) { _p = p; }
int& operator[](int col) { return _p[col]; }
};
class Matrix
{
private:
int* _p;
int _cols;
public:
Matrix( int rows, int cols ) { _cols=cols; _p = (int*)malloc(rows*cols ); }
Row operator[](int row) { return _p + row*_cols; }
};
So now, you can use the Matrix object, for example to create a multiplication table:
Matrix mtrx(rows, cols);
for( i=0; i<rows; ++i ) {
for( j=0; j<rows; ++j ) {
mtrx[i][j] = i*j;
}
}
You should now that the optimizer is doing the right thing and there is no call function or any other kind of overhead. No constructor is called. As long as you don't move the Matrix between function, even the _cols variable isn't created. The statement mtrx[i][j] basically does mtrx[i*cols+j].
It can be done as follows:
#define NUM_ROWS 10
#define NUM_COLS 10
int main(int argc, char **argv)
{
char (*p)[NUM_COLS] = NULL;
p = malloc(NUM_ROWS * NUM_COLS);
memset(p, 81, NUM_ROWS * NUM_COLS);
p[2][3] = 'a';
for (int i = 0; i < NUM_ROWS; i++) {
for (int j = 0; j < NUM_COLS; j++) {
printf("%c\t", p[i][j]);
}
printf("\n");
}
} // end of main
You can allocate (row*column) * sizeof(int) bytes of memory using malloc.
Here is a code snippet to demonstrate.
int row = 3, col = 4;
int *arr = (int *)malloc(row * col * sizeof(int));
int i, j, count = 0;
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
*(arr + i*col + j) = ++count; //row major memory layout
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
printf("%d ", *(arr + i*col + j));

Resources