数组指针详解

数组指针详解

前言 如需理解数组指针,需要先理解[[栈和堆]]。 数组指针详解: 现定义一个变量,并为其分配内存: char *buffer = (char *)malloc(100); *buffer = 'A'; 详解: buffer存储在栈中 buffer是一个局部变量,它是一个指针,存储在栈中。这个指针

前言

如需理解数组指针,需要先理解[[栈和堆]]。


数组指针详解:

现定义一个变量,并为其分配内存:

char *buffer = (char *)malloc(100);
*buffer = 'A';

详解:

  1. buffer存储在栈中

    • buffer是一个局部变量,它是一个指针,存储在栈中。这个指针buffer的值是malloc函数分配内存的首地址。
  2. *buffer: *buffer存储在堆中

    • *buffer是指针buffer指向内存地址处的值。通过malloc函数分配的 100 个字节的内存块位于堆中。可以通过*buffer访问和修改堆中内存的值。
  3. &buffer是指针buffer变量本身的地址

    • &buffer变量本身的地址在栈中,因为buffer是一个局部变量,这个地址与堆中内存地址无关。

为了更好地理解,可以查看代码运行时的内存图:

栈 (Stack):
+-----------------+
|     buffer      | -> 指向堆中分配的100字节内存块的首地址
|      ...        |
+-----------------+
| 返回地址等其他数据 |
+-----------------+

堆 (Heap):
+-----------------+
| *buffer ('A')   |
|     ... (99字节)  |
+-----------------+

拓展——操作堆内存中的数据:

  • 代码
char *buffer = (char *)malloc(100);

*buffer = 'A';
printf("%c\n", *buffer);
  • 输出
A
  • 代码
char *buffer = (char *)malloc(100);

buffer = "Hello, World!";
printf("%s\n", buffer);

*buffer = 'A';
printf("%c\n", *buffer);
  • 输出
Hello, World!
[1]    60387 bus error  ./demo

代码之所以会报错:
此处给buffer赋值,并非将Hello, World!写入到malloc分配的内存中,而是将buffer的值改为了字面值Hello, World!的地址。(可以理解为buffer重新指向了一块只读内存地址,内存中的数据是Hello, World!
而字面值存储在只读数据段中,如果尝试用*buffer修改,就会导致段错误(segmentation fault)。

正确做法:

#include <string.h>
strcpy(buffer, "Hello, World!");
*buffer = 'A';
  • 输出
Hello, World!
Aello, World!
  • 也可以通过snprintf函数来进行赋值
snprintf(buffer, 100, "Hello, World!");

如此一来,再通过*buffer修改buffer内存空间的值,就不会发生错误。

  • 值得了解的是,操作buffer的值,还可以通过“指针算数”的方式实现:
*buffer = 'A'; // 修改第一个内存处的值
*(buffer + 1) = 'B'; // 修改第二个内存处的值
buffer[2] = 'C'; // 修改第三个内存处的值

为了防止代码阅读性变差,应防止用第二种方式来读写。


任何时候都应注意,在堆中分配的内存,一定要在用完之后即使释放,防止内存泄漏!

LICENSED UNDER CC BY-NC-SA 4.0
Comment