tags:

views:

102

answers:

5

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

+1  A: 

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?

codaddict
You should mention why you got rid of that ugly unneeded cast.
mathepic
@Downvoter: Care to explain ?
codaddict
+3  A: 
   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);
Prasoon Saurav
You're forgetting the missing frees.
Matteo Italia
A: 

On line 6 you should have

a = (int**) malloc(sizeof(int*) * 5)); 
Daniel Băluţă
+5  A: 

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?

AndreyT
+3  A: 

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 freeing 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);
}
Matteo Italia