C Allocating Two Dimensional Arrays - c

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.

Related

What is the right way to initialize double pointer in 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);

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);

Arrays and malloc in C

Hello I am new to C and I need someone to explain concepts to me. I am a JAVA programmer and I am trying to write a program in C. My current issue is trying to initialize an array with an unknown number. I know in C an array has to be initialized with a number instead of a variable like you can in Java. My question is if I can do this in Java:
int i = 0;
char array [i];
void f(){
\\some code
i++;
}
How can I do this in C? I'm trying to fill an array with certain strings that I get from a file. I don't know how many I will be getting from the file however. I have tried reading about malloc but in one tutorial it says:
int *pointer;
pointer=malloc(2*sizeof(int));
is equivalent to
int array[2];
But I'm looking for a way to do this while increment the array.
First to mention, malloc() and family is used for dynamic (runtime) memory allocation whereas int arr[2] usually denotes compile time memory allocation. They are not exactly equivalent.
However, if you want to resize the allocated memory on-the-fly, you're on right track. What you need to do next is to use realloc() to re-size the previously allocated memory location.
You can read the man page for more details.
Also, while using dynamic memory in C, you need to keep in mid that there is no garbage collector in C. You need to free() up every bit of memory allocated by you.
I know in C an array has to be initialized with a number instead of a variable like you can in Java
In C99 and beyond, variable initiated arrays are available.
My current issue is trying to initialize an array with an unknown number.
and:
But I'm looking for a way to do this while increment the array.
If you have an unknown number of elements at run-time, you can write a function to create (and free) memory, passing the relevant arguments as you need them. Here is an example of a function to create (and free) a 2 dimensional array of ints:
int ** Create2Dint(int **arr, int cols, int rows)
{
int space = cols*rows;
int y;
arr = calloc(space, sizeof(int));
for(y=0;y<cols;y++)
{
arr[y] = calloc(rows, sizeof(int));
}
return arr;
}
void free2DInt(int **arr, int cols)
{
int i;
for(i=0;i<cols; i++)
if(arr[i]) free(arr[i]);
free(arr);
}
If, during execution, you need to change the allocation of memory (change the size of the array) you can use realloc(), implemented here in similar fashion:
int ** Realloc2D(int **arr, int cols, int rows)
{
int space = cols*rows;
int y;
arr = realloc(arr, space*sizeof(int));
for(y=0;y<cols;y++)
{
arr[y] = calloc(rows, sizeof(int));
}
return arr;
}
Usage example:
(execute with two integer command line arguments, both > 0)
int main(int argc, char *argv[])
{
int **array = {0};
int cols, rows;
cols = atoi(argv[1]);
rows = atoi(argv[2]);
array = Create2Dint(array, cols, rows);
//Do stuff here to use array
//Memory requirements change during runtime:
cols += 20;
rows += 50;
array = Realloc2D(array, cols, rows);
//use array again...
//When you are finished with the memory, free it:
free2DInt(array, cols);
return 0;
}

Runtime error in dynamically allocating 2D array in C

I am trying to dynamically allocate a 2D array, put some values, and print output. However it seems that I am making mistake in getting input to program in atoi() function.
Basically when we assign a static 2D array, we declare it as say int a [3][3]. So 3*3 units if int, that much memory gets allocated. Is same thing holds for allocating dynamic array as well?
Here is my code:
#include<stdio.h>
#include<stdlib.h>
int main(int arg,char* argv)
{
int rows = atoi(argv[1]);
int col = atoi(argv[2]);
int rows =3;
int col=3;
int i,j;
int (*arr)[col] = malloc(sizeof (*arr)*rows);
int *ptr = &(arr[0][0]);
int ct=1;
for (i=0;i<rows;i++)
{
for(j=0;j<col;j++)
{
arr[i][j]=ct;
ct++;
}
}
printf("printing array \n");
for (i=0;i<rows;i++)
{
for(j=0;j<col;j++)
{
printf("%d \t",arr[i][j]);
}
printf("\n");
}
free(arr);
return (0);
}
Program crashes in runtime. Can someone comment?
The first issue I see is this line:
int (*arr)[rows][col] = malloc(sizeof (*arr) * rows);
This is not problematic at all because you are in fact allocating more memory than you need. This would suffice:
int (*arr)[rows][col] = malloc(sizeof (*arr));
sizeof *arr is enough because *arr is of type int [rows][cols]; the memory you want is exactly the size of that array. The sizeof operator, when applied to arrays, gives you the count for the whole array.
The main problem with your code, however, is how you use arr. You are indexing it with arr[i][j], but instead, you should be using (*arr)[i][j], because arr is not an array, it's a pointer to an array. You need to dereference it before any further indexing - as simple as that. arr[i][j] is equivalent to *(*(arr+i)+j). Note that i should be an offset into *arr, not an offset on arr. That's why you need to dereference arr before indexing.
Since you're already using variable-length arrays, you may take advantage of that:
int (*arr)[col] = malloc(sizeof *arr * rows);
This way you can simply access elements with the usual syntax arr[i][j] without worrying about pointers and dereferences, pointer arithmetic will do all the work for you.
Also since indexes start from 0 your tests should look like i < rows and j < col.
And you have some minor errors for the wrong main declaration and the second printf.

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)

Resources