字符串二重指针为什么需要动态分配空间

指针的概念:创建一个指针类型的数据,在64位系统中,一个指针类型的数据用8个字节表示。指针类型的数据存储某个数据的地址。编译器,可以根据指针地址处理该地址的数据。

问题:字符串指针是指向字符串的指针,初始化字符串指针时,不需要为该字符串指针分配内存;而初始化字符串二重指针时,却需要用malloc为二重指针分配内存?

一重字符串指针

首先考虑字符串的存储模型,如下图所示。字符串变量s其实是存储了字符串首字母的地址,指针p为字符串首字母的地址。

输出字符串时,printf(),读入的地址认为是字符串的首地址,遇到“\0”,认为时字符串的结束。程序执行代码如下图所示。

#include <stdio.h>
#include <stdlib.h>

int main(void){
    char  *s = "abcdefgh"; 
    printf("s:%s\n", s);
    }

输出结果:

        s:abcdefgh

字符串指针初始化时,指定的是字符串常量,且字符串常量存储在代码区中,以后没法更改。可能是因为字符串常量,所以不需要为指针s分配内存。但如果字符串指针指向的不是字符串常量呢?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void){
    char *p = NULL;
    //~ p = malloc(7 * sizeof(char));
    
    strcpy(p, "123456");
    printf("p:%s\n", p);
    //~ free(p)
    }

在上面的代码中,将字符串”123456“复制,并用指针p指向复制后的字符串,运行程序,结果出现段错误。

如果取消注释的那行,为p在堆中分配7个字节的内存,则程序可正常输出如下:

        s:123456

所以呢,对于一重字符串指针来说,如果在初始化时指向字符串常量,就需要不在堆中分配空间,毕竟已经在代码块有个存储位置。但如果在初始化时,需要指向堆中的字符串,就必须在堆中先为字符串分配空间。

二重字符串指针

定义二重指针char **p,*p代表指向字符串的指针。

p指向的是指针的地址,而非字母的地址,可认为p指向了一个指针数组;这个指针数组并非存储在代码块的常量,所以需要在堆中为指针数组分配空间。假设需要m个字符串,就要为p分配m*sizeof(char *)的空间。

二重指针p的示意图如下所示。

p指向指针数组首地址,*p指向字符串地址,**p指向字符串首元素。

关于二重指针的代码如下所示:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	char **p;
	char  s1[10] = {'1' , '2', '3', '4', '5'};
	char * s2;
	p = malloc(2);
	s2 = "abcdefgh";
	*p = s1;
	p[1] = s2;
	
	printf("s0:%s\n", p[0]);
        printf("s1:%s\n", p[1]);
	free(p);
}

p指向的指针数组分别指向字符串s1的首地址,和s2的首地址。

函数可执行,输出如下:

          s:12345

          s:abcdefgh

说明二重字符串数组需要在堆中分配空间。

总结:

是否为字符串指针分配空间,依据为字符串指针指向的数据是否为堆中的数据。

1,一重指针如果指向字符串常量,则不需要为字符串常量分配空间;

2,一重指针如果指向需在堆中分配的字符串,比如一重指针为strcpy的目标地址,则需要为指针在堆中分配空间;

3,而二重指针始终指向字符串指针数组,不可能为存储在代码块的常量,所以必须为二重字符串指针在堆中分配空间。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值