C/C++中指针与数组的不同

疑问

首先通过下面例子抛出疑问:

  • define.c
#include <stdio.h>

char g_str[] = "KunQAQrz";

void define_print(void) {
  printf("define_print() : %s\n", g_str);
}
  • main.c
#include <stdio.h>

extern char* g_str;

int main() {
  define_print();
  printf("main() : %s\n", g_str);

  return 0;
}

对以上代码编译运行:
程序结果
为什么会发生段错误呢?下面将对错误进行分析。

原因分析

指针与数组

指针:

  • 指针的本质是一个变量,它保存的目标值是一个内存地址。
  • 指针运算与 * 操作符配合使用能够模拟数组的行为。

数组:

  • 数组是一段连续的内存空间
  • 数组名可看做指向数组第一个元素的常量指针。

指针与数组在汇编层面的不同

#include <stdio.h>

int main() {
  int a[3] = {0};
  int* p = a;

  p[0] = 1;
  p[1] = 2;

  a[2] = 3;

  return 0;
}

编译生成以上代码的可执行文件,并用objdump反汇编生成汇编代码。
以下为部分汇编代码:

  p[0] = 1;    /* 省略了加上偏移量的操作 */
    117b:	48 8b 45 e0          	mov    -0x20(%rbp),%rax
    117f:	c7 00 01 00 00 00    	movl   $0x1,(%rax)
  p[1] = 2;
    1185:	48 8b 45 e0          	mov    -0x20(%rbp),%rax  /* 将指针p存的地址传入寄存器中 */
    1189:	48 83 c0 04          	add    $0x4,%rax         /* 加上偏移量 */				  
    118d:	c7 00 02 00 00 00    	movl   $0x2,(%rax)       /* 将值赋值给寄存器所存地址的内存处 */	

  a[2] = 3;
    1193:	c7 45 f4 03 00 00 00 	movl   $0x3,-0xc(%rbp)   /* 直接将值赋值给对应内存处 */

通过上述汇编代码可得知,操作指针比操作数组多一个寻址操作
指针与数组的不同

解决疑问

通过原因分析了解到指针与数组在汇编层面是不同的,而疑问中的例子,将define.c中的g_str[]数组在main.c中当作指针来编译。这样得到的结果就是在main.c读取g_str会多一次寻址,从而访问野地址的内存。
错误描述
所以在main.c想要正常打印g_str的内容,传入g_str的地址即可:

  • main.c
#include <stdio.h>

extern char* g_str;

int main() {
  define_print();
  printf("main() : %s\n", &g_str);

  return 0;
}

结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值