C中的指针(应该很简单)

lyn*_*ilu 2 c pointers

我试过这样的代码:

int *a;
*a = 10;
printf("%d",*a);
Run Code Online (Sandbox Code Playgroud)

在日食中它并没有打印出任何东西.是因为我没有给出初值?


谢谢你的帮助.我知道这是有问题的我只是不确定确切的问题,如果我这样做printf("%d",a);我可以看到它确实包含一些东西,是C的规则,我必须给它一个指向的地方然后我可以开始改变那个地址的价值?

pho*_*xis 15

  • int *a; 这定义了一个变量,它是一个指向整数类型的指针.创建时的指针类型变量a包含垃圾值.
  • 当你这样做*a = 10;时,使用存储的值a(垃圾)作为地址并将值存储在10那里.因为我们不知道a包含什么并且没有分配,所以a指向一些未知的存储位置并且访问它将是非法的,并且会给你一个分段错误(或类似的东西).
  • 同样的情况printf ("%d", *a);.这也会尝试访问存储在您尚未分配的某个未定义内存位置的值.

.

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 |---->| ?????   |
+-------+---------+     +---------+
Run Code Online (Sandbox Code Playgroud)

在定义了指针类型变量之后,需要从操作系统请求一些内存位置并使用该内存位置值存储a,然后使用该内存位置a.

为此,您需要执行以下操作:

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.
           */
Run Code Online (Sandbox Code Playgroud)

在这种情况下,它如下所示:

之后*a = 10;.指针变量在堆栈中分配.此时a包含垃圾值.然后a指向具有该垃圾值的地址.

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 |---->| ?????   |
+-------+---------+     +---------+
Run Code Online (Sandbox Code Playgroud)

之后a = (int *) malloc (sizeof (int));.让我们假设malloc返回一些地址0x1234abcd,以供使用.这时a将包含0x1234abcd然后a点到被分配并保留使用您有效的存储位置.但请注意,里面的值0x1234abcd可以是任何东西,即.垃圾.您可以使用它calloc来设置分配给的内存位置的内容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|
+-------+------------+     +---------+
Run Code Online (Sandbox Code Playgroud)

之后*a = 10;,通过*a访问内存位置0x1234abcd并存储10到其中.

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   |
+-------+------------+     +---------+
Run Code Online (Sandbox Code Playgroud)

之后free (a),aie 的内容.内存地址0x1234abcd将被释放,即返回给操作系统.请注意,释放后0x1234abcd的内容仍然a是,但你不能再合法地访问它,因为你刚刚释放它.访问存储在其中的地址所指向的内容将导致未定义的行为,最可能是分段错误或堆损坏,因为它已被释放且您没有访问权限. 0x1234abcda

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.
Run Code Online (Sandbox Code Playgroud)

EDIT1

另外要注意的区别printf ("%d", a);printf ("%d", *a);.当您参考a,它只是简单地打印的内容a0x1234abcd.当你引用*a然后它0x1234abcd用作地址,然后打印地址的内容,10在这种情况下.

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);
Run Code Online (Sandbox Code Playgroud)

EDIT2

另请注意,malloc无法获得有效的内存位置.您应该始终检查是否malloc返回了有效的内存位置.如果malloc无法获得某些内存位置,那么它将返回给您,NULL因此您应该NULL在使用前检查返回的值是否存在.所以最后代码变成了:

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.
           */
Run Code Online (Sandbox Code Playgroud)


jml*_*pez 10

你没有为a分配内存.

尝试

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.
Run Code Online (Sandbox Code Playgroud)

  • 不要忘记1.检查`malloc`失败,以及2.`free`. (5认同)