Adobe Interview Question
Software Engineer / DevelopersAssumes that void* and int are the same size. Anybody who does that is not welcome in my shop.
Approach 2 (using malloc only once) (revised):
void *temp = (void *) malloc(r*sizeof(int *) + (r*c)*sizeof(int));
int **arr = (int **)temp;
arr[0] = (int *)(arr+r);
arr[1] = (int *) (arr+r+c);
arr[2] = (int *) (arr+r+2c);
.
.
arr[r-1] = (int *) (arr+r+(r-1)c);
Approach 2 (using malloc only once) (revised, ignore the previous one):
void *temp = (void *) malloc(r*sizeof(int *) + (r*c)*sizeof(int));
int **arr = (int **)temp;
arr[0] = (int *)(arr+r);
arr[1] = (int *) (arr+r+c);
arr[2] = (int *) (arr+r+2c);
.
.
arr[r-1] = (int *) (arr+r+(r-1)c);
Hello, your both approach works fine. I am finding some problem in grasping your 2nd approach.Can you please give some explanation for 2nd approach(using one malloc).
@Spsneo:
arr[i] = (int*)( arr + r + (i-1)*c ) needs to have 2 changes::
1) r should be replace by r*sizeof(int*). The first chunk of memory is an array of r integer pointers. To pass that, we need to add r*sizeof(int*) bytes to int** arr.
2) (i-1)*c should be replaced by (i-1)*sizeof(int)*c. The reasoning being the same as above.
R,C defined ;
int** arr=(int**)malloc(sizeof(int*)*R);
for(i=0;i<R;i++)
arr[i]=(int*)malloc(sizeof(int)*C );
Approach -2 :
int**arr=(int**)malloc(sizeof(int)*R*C);
int*ptr=*arr;
for(i=0;i<R;i++)
{
*(arr+i)=( ptr+i*C ) ;
}
Approach 1 uses malloc R times . So it is not acceptable.
Approach 2 is wrong. Figure out why.
Excluding the undeclared loop variable and the possibility of integer overflow, could you enlighten us as to why this approach is wrong?
Assuming r,c is defined.
Approach 1 (using malloc 2 times):
int **arr = (int *) malloc(r*sizeof(int *));
int *temp = (int) malloc(r*c*sizeof(int));
arr[0] = temp;
arr[1] = temp+c;
arr[2] = temp+2c;
..
..
arr[r-1] = temp+(r-1)c;
Well... If the question is to allot space for a 2D array of say 10*10 we can do something of this sort as well
int* p= (int *)malloc(sizeof(int)*10*10);
Does this satisfy the constraints ?
No it does not satisfy the constraints. There should be a variable (say arr), such that we can access the elements like arr[i][j].
Your solution will not do that.
But it does... Say I want to access the 3 element of the 10th row, then all I got to do is write
printf("%d\n",*(p+ 9*R +3)
where R is the number of elements in each row
yeah thats what, you will have to access using that clumsy form. You can't access it like p[9][3]. The interviewer asked to write a function which will return a pointer and normal programmer could access that variable normally. And I guess you understand that what you have written is normal.
Otherwise the question is trivial.
char** My2DAlloc(int row, int col)
{
char **r = NULL;
int i = 0;
if((row == 0) || (col == 0))
return NULL;
/* Allocate memory for row pointers */
r = (char**)malloc(row*sizeof(char*));
assert(r != NULL);
for(i=0; i<row; i++)
{
*(r+i) = (char*)malloc(col);
assert((char*)(*(r+i)) != NULL);
}
return r;
}
char** My2DAlloc_twice(int row, int col)
{
char **r = NULL;
char *c = NULL;
int i = 0;
if((row == 0) || (col == 0))
return NULL;
/* Allocate memory for row pointers */
r = (char**)malloc(row*sizeof(char*));
assert(r != NULL);
c = (char*)malloc(row*col);
assert(c != NULL);
for(i=0; i<row; i++)
{
*(r+i) = (char*)(c + i*col);
}
return r;
}
char** My2DAlloc_once(int row, int col)
{
char **r = NULL;
char *loc = NULL;
int i = 0;
if((row == 0) || (col == 0))
return NULL;
/* Allocate memory for row pointers */
r = (char**)malloc(row*sizeof(int*)+ row*col);
assert(r != NULL);
loc = r + row; //Addition of pointers advances bytes = num*sizeof(data type)
for(i=0; i<row; i++)
{
*(r+i) = (char*)(loc + i*col);
}
return r;
}
char** My2DAlloc(int row, int col)
{
char **r = NULL;
int i = 0;
if((row == 0) || (col == 0))
return NULL;
/* Allocate memory for row pointers */
r = (char**)malloc(row*sizeof(char*));
assert(r != NULL);
for(i=0; i<row; i++)
{
*(r+i) = (char*)malloc(col);
assert((char*)(*(r+i)) != NULL);
}
return r;
}
char** My2DAlloc_twice(int row, int col)
{
char **r = NULL;
char *c = NULL;
int i = 0;
if((row == 0) || (col == 0))
return NULL;
/* Allocate memory for row pointers */
r = (char**)malloc(row*sizeof(char*));
assert(r != NULL);
c = (char*)malloc(row*col);
assert(c != NULL);
for(i=0; i<row; i++)
{
*(r+i) = (char*)(c + i*col);
}
return r;
}
char** My2DAlloc_once(int row, int col)
{
char **r = NULL;
char *loc = NULL;
int i = 0;
if((row == 0) || (col == 0))
return NULL;
/* Allocate memory for row pointers */
r = (char**)malloc(row*sizeof(int*)+ row*col);
assert(r != NULL);
loc = r + row; //Addition of pointers advances bytes = num*sizeof(data type)
for(i=0; i<row; i++)
{
*(r+i) = (char*)(loc + i*col);
}
return r;
}
I have one question about these solutions. They all require more memory than the standard array. If one placed the following in a function
int array[20[3];
sizeof(array)
the 'sizeof' function would return the value 24. If one were then to add the following
printf ("testArray[0]= %x\n", &(testArray[0]) );
printf ("testArray[0][0]= %x\n", &(testArray[0][0]) );
printf ("testArray[1]= %x\n", &(testArray[1]) );
printf ("testArray[1][0]= %x\n", &(testArray[1][0]) );
one would find that the following two conditions to be true:
&(testArray[0]) == &(testArray[0][0])
&(testArray[1]) == &(testArray[1][0])
I cannot, however find a way to make these two conditions true when using the algorithms described here to setup an array in a segment of malloc'ed memory.
typedef int twodptr[2][2];
void func()
{
int *ptr = (int*)calloc(1, sizeof(int) * (2 * 2));
ptr[0] = 0; ptr[1] = 1; ptr[2] = 2; ptr[3] = 3;
twodptr *ptr2 = (twodptr*)ptr;
(*ptr2)[0][0] = 10;
(*ptr2)[0][1] = 11;
(*ptr2)[1][0] = 12;
(*ptr2)[1][1] = 13;
free (ptr);
}
2d array:
1. using 2 malloc
int **p = (int**)malloc(sizeof(int*) * ROWS);
for(int i = 0;i<ROWS; i++)
p[i] = (int*)malloc(sizeof(int) * COLS);
p[i][j] = p[i][j]
2. using 1 malloc
int *p = (int*)malloc(sizeof(int) * ROWS * COLS);
p[i][j] = *(p+i*COL+j);
for 3d array:
int ***p = (int***)malloc(sizeof(int**) * SET);
for(int i=0;i<SET;i++)
{
p[i] = (int**)malloc(sizeof(int*) * ROWS);
for(int j=0;j<ROWS;j++)
p[i][j] = (int*)malloc(sizeof(int) * COL);
}
Approach 2 (using malloc only once):
- spsneo January 25, 2010void *temp = (void *) malloc((r+r*c)*sizeof(void *));
int **arr = (int **)temp;
arr[0] = (int *)(temp+r);
arr[1] = (int *)(temp+r+c);
arr[2] = (int *)(temp+r+2c);
.
.
arr[r-1] = (int *)(temp+r+(r-1)c);