What is the right way to initialize double pointer in c - c

As title, I want to know how to initialize double pointer with sizeof a pointer.
For instance
int **p=malloc(sizeof *p * rows);
for(size_t i = 0; i < rows; i++){
p[i]=malloc(sizeof ? * cols);
}
What should I fill in ?.
Any help would be appreciated.

What should I fill in ?.
In general when you have
X = malloc(sizeof ? * NUMBER);
the ? is to be replaced with the type that X points to. That can simply written as *X.
So the line:
p[i]=malloc(sizeof ? * cols);
is to be:
p[i]=malloc(sizeof *p[i] * cols);
Notice that a 2D array can be created much simpler. All you need is
int (*p)[cols] = malloc(sizeof *p * rows);
Here p is a pointer to an array of cols int. Consequently sizeof *p will be the size of an array of cols int.
Using this VLA based technic means that you can allocate the 2D array using a single malloc. Besides making the code more simple (i.e. only 1 malloc) it also ensures that the whole 2D array is in consecutive memory which may give you better cache performance.

It looks like you want p to be an array that can hold pointers, and the number of pointers is rows. So you can allocate memory for p like this:
int ** p = malloc(sizeof(int *) * rows);
Now if you want p[i] to point to an array that holds cols ints, do this:
p[i] = malloc(sizeof(int) * cols);

Related

How to initialize rows of 2D array of strings in C

I want to store strings in a 2D array using pointers but I'm confused with how to do it. The examples I've seen use only arrays of ints or use the brackets[] to allocate a fixed size of memory. So I'm trying to initialize my 2D array of strings and this is what I have:
char ** stringArr = (char**)malloc(/*I don't know what goes here*/);
for(i = 0; i < rows; i++)
stringArr[i] = (char*)malloc(cols *sizeof(char));
As you can see the parameter for my first call of malloc, I am stuck as to what to put there if I want an exact x number of rows, where each row stores a string of chars. Any help would be appreciated!
Do this, because you're allocating some number of pointers:
malloc(rows * sizeof(char*))
You will want to use the number of rows.
char ** stringArr = malloc(rows * sizeof(char*));
Also, do not typecast the return value of a malloc() call.
Use sizeof *ptr * N.
Notice how this method uses the correct type even if stringArr was char ** stringArr or int ** stringArr.
stringArr = malloc(sizeof *stringArr * rows);
for(i = 0; i < rows; i++)
stringArr[i] = malloc(sizeof *(stringArr[i]) * cols);

Am I correctly allocating memory for my pointer arrays in C?

I am trying to track down a bug a big program. I think it is due to how I am passing arrays to my functions. Am I doing this correctly?
main(){
int *x = declarArray(x, 100);
int *y = declarArray(x, 100);
// lines of code....
x = arrayManip(x, 100);
// more code...
int i;
for(i=0; i<100; i++)
y[i] = x[i];
//more code...
free(x);
free(y);
}
This is how I manipulate arrays:
int *arrayManip(int *myarray, int length){
int i;
for(i=0; i<length; i++)
myarray[i] = i;
return array;
}
This is how I initialize the arrays:
int* declareArray(int *myarray, int length){
myarray = (int*) malloc(length*sizeof(int*));
if (myarray==NULL)
printf("Error allocating memory!\n");
int i;
for(i=0; i<length; i++)
myarray[i] = -888;
return myarray;
}
This code seems to work fine on a small scale, but maybe there is a problem once I have many more arrays of larger size that are often getting passed back and forth and copied in my program?
declarArray :
Name is not gramatically correct
The name of the function is not what it does
malloc with sizeof(int*), not sizeof(int). Guarantuee to be a bug in 64 bit machine
malloc fails, you print, but still write to null
passing myarray as argument is a noop as is
-888 is a magic number
There is no error check whatsoever
My advice. Throw it away and start fresh
No, as per my understanding.
You allocating one dim array => elements in that array should be integers and not pointers to integers so instead of this :
myarray = (int*) malloc(length*sizeof(int*));
it should be :
myarray = (int*) malloc(length*sizeof(int));
In function arrayManip you pass param named array, and than you trying to access it as myarray
This:
myarray = (int*) malloc(length*sizeof(int*));
allocates an array of length pointers to an integer, but then puts it into a pointer to an integer (i.e. an array of integers, not pointers to integers). If you want an array of integers, you want:
myarray = (int*) malloc(length*sizeof(int));
or (if you want to zero it):
myarray = (int*) calloc(length, sizeof(int));
which does the size x length calculation itself.
To allocate a list of pointers to integers, you want:
myarray = (int**) malloc(length*sizeof(int*));
or
myarray = (int**) calloc(length, sizeof(int*));
Unless you are fantastically concerned about speed, I find using calloc() results in fewer bugs from uninitialized arrays, and makes the reason for the allocated size more obvious.
The pointer is of word size [2 or 4 ,... depending on machine architecture]. whatever it may point to int,double,float,...
for integer pointer it works if it takes 4 bytes for int in machine. when u go for other data type it 'll lead you to error.
you should allot memory as
pointer = (DataType*) malloc (length * sizeof(DataType));
use malloc and to make your code clear.
void* malloc (size_t size);
malloc reference
use memset to allot default value [-888] for your array.
void *memset(void *str, int c, size_t n)

free a double pointer

I created a 2-D matrix using double pointer like that:
int** pt; pt = (int*) malloc(sizeof(int)*10);
I know that a pointer is freed like that
free(ptr);
How can we free the double pointer?
What if we print something and later freed that memory and exit the program? Does the final memory consist of that which we used or it will be same as initial?
Say you have a matrix mat
int** mat = malloc(10 * sizeof(int*));
for (int i=0; i<10; ++i) {
mat[i] = malloc(10 * sizeof(int));
}
then you can free each row of the matrix (assuming you have initialized each correctly beforehand):
for (int i=0; i<10; ++i) {
free(mat[i]);
}
then free the top-level pointer:
free(mat);
For your second question: if you allocate memory and use it, you will change that memory, which will not be "reverted" even if you free it (although you will not be able to access it reliably/portably any more).
Note: the top-level malloc is using sizeof(int*) as you are allocating pointer-to-ints, not ints -- the size of int* and int are not guaranteed to be the same.
If your matrix isn't "ragged", i.e. all rows have the same length, you might want to consider:
Accessing it manually, i.e. just treat it as a 1D array of values, and keep a separate width value. To access an element at (x,y) use mat[y * width + x].
If you really want the convenience of mat[y][x], you can improve it by doing a single call to malloc() that allocates both the pointer array and all the rows, then initializing the pointers to point at each row. This has the advantage that it can all be free:ed with a single free(mat); call.
The second approach would look something like this:
double ** matrix_new(size_t width, size_t height)
{
double **p = malloc(height * sizeof *p + width * height * sizeof **p);
double *e1 = (double *) (p + height);
size_t i;
for(i = 0; i < height; ++i)
p[i] = e1 + i * width;
return p;
}
Note: the above is un-tested, and production code should obviously check for failure before using p.
For the first question, I'll tell you the rule of thumb.
The number of times you call free() should be equal to the number of times you call malloc() + the number of times you call calloc().
So if you allocated in such a way that you made a pointer to pointers to ints, and then used malloc() on each pointer to ints, then you'll free "row" number of times, where each free() is for each pointer to ints.
And a final free() is called on the pointer to pointers to ints. That will balance out the malloc() + calloc() with free() calls.

C Allocating Two Dimensional Arrays

I am trying to allocate a 2D dimension array of File Descriptors... So I would need something like this
fd[0][0]
fd[0][1]
I have coded so far:
void allocateMemory(int row, int col, int ***myPipes){
int i = 0,i2 = 0;
myPipes = (int**)malloc(row * sizeof(int*));
for(i = 0; i < row;i++){
myPipes[i] = (int*)malloc(col * sizeof(int));
}
}
How can I set it all too zeros right now I keep getting a seg fault when I try to assign a value...
Thanks
So, first, you're going to have to pass in a pointer to myPipes:
void allocateMemory(int rows, int cols, int ***myPipes) { ... }
Then it's easy:
*myPipes = malloc(sizeof(int) * rows * cols);
And of course, you'd call it with:
int **somePipes;
allocateMemory(rows, cols, &somePipes);
short answer: change your innermost malloc to a calloc.
long answer provided by the c faq:
http://c-faq.com/~scs/cclass/int/sx9b.html
What you need to understand is that C doesn't really have a way to allocate a true multidimensional array. Instead, you just have a pointer to an array of pointers. Treat your data structure as such and you will be fine.

Dynamic allocation (malloc) of contiguous block of memory

For an assignment, I have to allocate a contiguous block of memory for a struct, but I'm first trying to do it with a 2D array of ints first and see if I understand it correctly. We had an example in the book that creates a block of memory for the pointer array (rows), and then initializes the cols and points the pointer to them. This example was:
int **CreateInt2D(size_t rows, size_t cols)
{
int **p, **p1, **end;
p = (int **)SafeMalloc(rows * sizeof(int *));
cols *= sizeof(int);
for (end = p + rows, p1 = p; p1 < end; ++p1)
*p1 = (int *)SafeMalloc(cols);
return(p);
}
void *SafeMalloc(size_t size)
{
void *vp;
if ((vp = malloc(size)) == NULL) {
fputs("Out of mem", stderr);
exit(EXIT_FAILURE);
}
return(vp);
}
I basically need to do what the above code does except make it one contiguous block of memory. The constraint is I'm only allowed to call malloc once, and then I have to use pointer math to know what to initialize the pointers to. So I thought I would initialize enough memory with something like:
int *createInt2D(size_t rows, size_t cols)
{
malloc(rows * sizeof(int *) + (row + cols) * sizeof(int));
}
But that doesn't seem quite right since I would think I would have to typecast the void * returned from malloc, but it's a combination of int and int*. So I'm not quite sure if I'm on the right track. Thoughts?
If you want a contiguous array, you should malloc(rows * cols * sizeof(int)).
Then you'd access arr[x, y] like:
arr[x * cols + y]
You are on the right track. The block returned by malloc is guaranteed to be aligned properly for either int * or int; you can use it for either. Typecasting isn't a one time operation.
If you are going to use array[row, col] addressing exclusively, you can get by without allocating extra space for the row pointers. If you would like to be able to use array[row] to get an int * column list, you'll have to include space for the column pointers in your allocation.
Hope that's enough to help with your exercise.
malloc((row * cols) * sizeof(int));
It's row*cols which is number of elements in the 2D array and not row+cols.
No need to multiply by the size of int *. That's only used to allocate the pointers for the rows. Same too with the sum of rows and cols. It's sufficient to allocate (rows * cols) * sizeof whatever structure is being allocated.

Resources