【字符串两大注意事项】
表达字符串的方式
1.双引号:"hello world"
2.字符指针:char* ptr = "hello world"
3.字符数组:char arr[] = "hello world"
辨析
项目 | 表示方式 | 代表含义 | 内存分布 |
---|---|---|---|
1 | “hello world” | 字符串字面量 | 字符串常量就是数据段,或者是rodata段(只读数据段) |
2 | 字符指针 | 指向存储字符串的内存起始虚拟地址 | 与所指地址有关,字符串常量就是数据段,或者是rodata段(只读数据段) |
3 | 字符数组 | 在栈区开辟的一块字符字节的内存区域 | 栈区 |
实践验证
#include <iostream>
#include <cstring>
using namespace std;
int main(void) {
char *ptr = "datouerzi";
char arr[] = "xiaotoubaba";
cout << "指针ptr的地址是:" << static_cast<void*>(ptr) << endl;
cout << "指针ptr的所指的是:" << ptr << endl;
cout << "arr的地址是:" << static_cast<void*>(arr) << endl;
cout << "arr所指的是:" << arr << endl;
}
运行结果如下
指针ptr的地址是:0x561a4eeb3ba5
指针ptr的所指的是:datouerzi
arr的地址是:0x7ffea05062de
arr所指的是:datouerzi
arr的地址是:0x7ffea05062de,0x7ff开头说明内存空间在栈区。指针ptr的地址是:0x561a4eeb3ba5说明在数据段,或者是rodata段,也就是字符串"datouerzi"所存储的内存地址。
常见两个错误
1.无法修改指针ptr所指向的字符串常量的内容
char *ptr = "datouerzi";
strcpy(ptr, "xiaotoubaba");
运行结果直接报错段错误。原因就是因为ptr指针已经指向了存储在只读数据段的字符串常量"datouerzi",尝试将 “xiaotoubaba” 复制到只读内存区域会导致段错误,因为只读内存区域不能被修改。
有如下两种对应方法:
1.使用malloc或者calloc动态的分配内存(堆)。
char *ptr = "datouerzi";
ptr = static_cast<char*>(malloc(50));
strcpy(ptr, "xiaotoubaba");
...
free(ptr);
2.创建字符数组来开辟一块内存(栈)
char *ptr = "datouerzi";
char arr1[20] = {'0'};
ptr = arr1;
strcpy(ptr, "xiaotoubaba");
...
- arr = p; //编译报错 其实是char *const arr