Reputation: 135
hi thanx every body for their support but no one provide me the required information now i try to did that program like this
#include<stdio.h>
#include <stdlib.h>
int main()
{
int **a,i,j;
system("clear");
a=(int*)malloc(sizeof(int)*5);
for (i=0; i<5; i++)
{
a[i]= malloc(sizeof(int)*3);
for (j=0; j<3; j++)
{
printf("\nplease enter the [%d][%d] location = ",i,j);
scanf("%d",&a[i][j]);
}
}
for (i=0; i<5; i++)
{
for (j=0; j<3; j++)
{
printf("\nthe value enter enter the [%d][%d] location = ",i,j);
printf("%d",a[i][j]);
}
}
free(a);
return ;
}
i complied it on compilation it shows warnig which is following
c:8: warning: assignment from incompatible pointer type
on running the program it take 15 value from user but it did not show the value entered by user can anybody explain what i'm doing wrong ,can any body explain me the concept of double pointer & dynamic memory allocation
Upvotes: 0
Views: 265
Reputation: 320391
Firstly, the memory allocation in your code is incorrect. The first malloc
should look as follows
a = (int **) malloc(sizeof(int *) * 5);
Your a
is int **
, as you declared it. You are casting the result of malloc
to int *
. int *
and int **
are those incompatible types the compiler is warning you about. To avoid such errors in the future, get rid of the bad habit of using types in statements. Types in C belong in declarations. Statements should be as type-independent as possible. The above malloc
call would look much better this way
a = malloc(5 * sizeof *a);
Note: no cast, no types mentioned. The second malloc
would look as follows
a[i] = malloc(3 * sizeof *a[i]);
I hope you see the pattern in accordance with which these malloc
calls are built.
You also forget to deallocate memory for individual sub-arrays in your program (a[i]
memory is never deallocated, while a
memory is).
As for the program not showing the entered values... The first problem with broken malloc
call is serious enough to prevent your program from working, but it still might appear to "work" on some platforms. On such platforms it should show the values. Are you sure you are not simply missing the output?
Upvotes: 3
Reputation: 126787
This code has several errors. First of all, the warning refers to the fact that you're trying to assign a pointer to integer (int *
) to a variable (a
) which is a pointer to a pointer to integer (int **
), which you actually want to use as an array of arrays.
So, first correction, at line 8 it's not
a=(int*)malloc(sizeof(int)*5);
but it is
a=(int**)malloc(sizeof(int *)*5);
(that cast in C isn't strictly necessary, but being a C++ programmer I prefer to keep it like that)
Notice that also the expression in the sizeof
changed, since what you want to allocate is not the space for five integers, but the space for five pointers to integers.
Then, at the end of the application, you're free
ing just the space allocated with the first malloc
, while you made other five allocations (one for each row). Thus, you could do the deallocation in the last cycle, just after displaying each row.
for (i=0; i<5; i++)
{
for (j=0; j<3; j++)
{
printf("\nthe value enter enter the [%d][%d] location = ",i,j);
printf("%d",a[i][j]);
}
free(a[i]);
a[i]=NULL;
}
free(a);
a=NULL;
Remember: for each malloc
or calloc
, you have to have it's corresponding free
, otherwise you're leaking memory.
Here, after each deallocation, I set the corresponding pointer to NULL
to throw away those old, now-invalid, pointers. Somebody say that this behavior can mask double-frees (since free(NULL)
doesn't produce errors), but IMHO this is better than the alternative
One important detail: you're not checking the return value of malloc
, which is quite bad. It's extremely unlikely that in such small programs allocations may fail, but, nonetheless, it's good practice to always check if the return value of malloc
is NULL
, and, in this case, handle the situation gracefully, usually releasing all the resources and shutting down the application.
By the way, system("clear");
is ugly. You should use the platform-specific way to clean the screen, even better if enclosed in a function; on Linux with normal (X3.64) terminal emulators something like this could be ok:
void ClearScreen()
{
fputs("\x1B[2J\x1B[1;1H", stdout);
fflush(stdout);
}
Upvotes: 3
Reputation: 92854
a = (int*)malloc(sizeof(int)*5);
^
|
Warning due to this
a
is a pointer to pointer to int
i.e int **
.
You are casting malloc()
's return value to int*
and then assigning it to int**
so the implicit conversion from int*
to int**
generates the warning. Moreover it should be sizeof(int *)
inside first malloc()
[as you are trying to allocate memory for a two dimensional array].
Try this :
a=(int**)malloc(sizeof(int*)*5);
Upvotes: 1
Reputation: 454960
a
points to an array of int
pointers. So each element of that array is of type int*
not int
. So you should be using sizeof(int*)
.
this
a = (int*)malloc(sizeof(int)*5);
should be
a = malloc(sizeof(int*)*5);
^
As malloc in C returns a void
pointer and C implicitly casts from and to void*
there is no need of a cast.
You might want to read this:
Should I explicitly cast malloc()'s return value?
Upvotes: 1
Reputation: 1275
On line 6 you should have
a = (int**) malloc(sizeof(int*) * 5));
Upvotes: 0