开发者

Pointer in C (should be simple)

I tried code like this:

int *a;
*a = 10;
printf("%d",*a);

in eclipse and it is not printing out anything. is it because I haven't give initial value to a?


Thank you that was helpful. I know it is problematic I just wasn't sure the exact problem like, if I do printf("%d",a); I can see it does contain something, is it C's rule tha开发者_如何学Ct I do have to give it a place to point to then I can start to change the value in that address?


  • int *a; This defines a variable which is a pointer to an integer type. The pointer type variable a at the creation contains garbage value.
  • When you do *a = 10; it ties to use the value stored in a , which is garbage, as an address and store the value 10 there. Because we do not know what a contains and it is not allocated so a points to some memory location which is unknown and accessing it will be illegal, and will get you a segmentation fault (or something similar).
  • Same in the case of printf ("%d", *a); . This also tries to access the value stored at some undefined memory location which you have not allocated.

.

this variable is       this is the location
stored in some         with the address 
address on the         'garbage'. You do not
stack                  have permissions to
                       access this
+-------+---------+
| name  | value   |
+-------+---------+     +---------+
|  a    | garbage |---->| ?????   |
+-------+---------+     +---------+

After you have defined the pointer type variable, you need to request for some memory location from the operating system and use that memory location value to store into a, and then use that memory location through a.

To do that you need to do the following:

int *a;

a = malloc (sizeof (int)); /* allocates a block of memory
                                    * of size of one integer
                                    */

*a = 10;
printf ("%d", *a);


free (a); /* You need to free it after you have used the memory 
           * location back to the OS yourself.
           */

In this case it is like below:

After *a = 10; . The pointer variable is allocated in the stack. At this moment the a contains a garbage value. Then a points to an address with that garbage value.

this variable is       this is the location
stored in some         with the address 
address on the         'garbage'. You do not
stack                  have permissions to
                       access this
+-------+---------+
| name  | value   |
+-------+---------+     +---------+
|  a    | garbage |---->| ?????   |
+-------+---------+     +---------+

After a = (int *) malloc (sizeof (int)); . Let us assume that malloc returns you some address 0x1234abcd, to be used. At this moment a will contain 0x1234abcd then a points to a valid memory location which was allocated and reserved for you to be used. But note that the value inside 0x1234abcd can be anything, ie. garbage. You can use calloc to set the contents of the memory locations you allocate to 0.

this variable is       this is the location
stored in some         0x1234abcd , allocated
address on the         by malloc, and reserved
stack                  for your program. You have
                       access to this location.
+-------+------------+
| name  | value      |
+-------+------------+     +---------+
|  a    | 0x1234abcd |---->|  garbage|
+-------+------------+     +---------+

After *a = 10; , by *a you access the memory location 0x1234abcd and store 10 into it.

this variable is       this is the location
stored in some         0x1234abcd , allocated
address on the         by malloc, and reserved
stack                  for your program. You have
                       access to this location.
+-------+------------+
| name  | value      |
+-------+------------+     +---------+
|  a    | 0x1234abcd |---->|    10   |
+-------+------------+     +---------+

After free (a) , the contents of a ie. the memory address 0x1234abcd will be freed, ie returned back to the operating system. Note that after freeing the 0x1234abcd the contents of a is still 0x1234abcd , but you can no more access it legally, because you just freed it. Accessing the contents pointed by the address stored in a will result in undefined behavior, most probably a segmentation fault or heap corruption, as it is freed and you do not have access rights.

this variable is       this is the location
stored in some         0x1234abcd , allocated
address on the         by malloc. You have freed it.
stack                  Now you CANNOT access it legally

+-------+------------+
| name  | value      |
+-------+------------+     +---------+
|  a    | 0x1234abcd |     |    10   |
+-------+------------+     +---------+

the contents of a remains
the same.

EDIT1

Also note the difference between printf ("%d", a); and printf ("%d", *a); . When you refer to a , it simply prints the contents of a that is 0x1234abcd. And when you refer *a then it uses 0x1234abcd as an address , and then prints the contents of the address, which is 10 in this case.

this variable is       this is the location
stored in some         0x1234abcd , allocated
address on the         by malloc, and reserved
stack                  for your program. You have
                       access to this location.
+-------+------------+
| name  | value      |
+-------+------------+     +---------+
|  a    | 0x1234abcd |---->|    10   |
+-------+------------+     +---------+
              ^                 ^
              |                 |
              |                 |
      (contents of 'a')   (contents of the   )
              |           (location, pointed )
printf ("%d", a);         (    by 'a'        )
                                |
               +----------------+
               |
printf ("%d", *a);

EDIT2

Also note that malloc can fail to get you some valid memory location. You should always check if malloc returned you a valid memory location. If malloc cannot get you some memory location to be used then it will return you NULL so you should check if the returned value is NULL or not before use. So finally the code becomes:

int *a;

a = malloc (sizeof (int)); /* allocates a block of memory
                                    * of size of one integer
                                    */

if (a == NULL)
{
  printf ("\nCannot allocate memory. Terminating");
  exit (1);
}

*a = 10;
printf ("%d", *a);


free (a); /* You need to free it after you have used the memory 
           * location back to the OS yourself.
           */


You haven't allocated memory for a.

Try

int *a;
a = (int*)malloc(sizeof(int)); //Allocating memory for one int.

*a = 10;
printf("%d", *a);
free(a); //Don't forget to free it.


When you declare the pointer, the compiler is only going to reserve memory to store a pointer variable. If you want that pointer to point to something after the fact, it has to be something that had its own memory allocated. Either point it at something that was declared as an int, or allocate memory from the heap for an int.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜