---
title: "字符串指针作为参数与空间分配问题"
author: "Perrin Yong"
author_profile: https://www.pystone.net/profile/
published_by: "Perrin Yong"
canonical: https://www.pystone.net/notes/cpp-string-pointer-param-memory-allocation/
type: note
content_role: unspecified
visibility: public
id_stability: rename-stable
source_path: "10-计算机、信息技术与工程/02-编程语言与运行时/C++/字符串指针作为参数与空间分配问题.md"
content_hash: de0499dfe8340cb70be7fd7374d38c567f06c726cfe8561d43abe67b0aacf0f5
knowledge_version: 224c990773de.5fa8af6e39fa
site_commit: 224c990773de166d23a886306577dd90379529ce
notes_commit: 5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a
---
# 字符串指针作为参数与空间分配问题

﻿# 字符串指针作为参数与空间分配问题

> 创建时间：2020/3/14 22:34

## 小知识点：

### 输出指针值

>
```cpp
string str1 = &quot;test&quot;;
string str2 = &quot;test&quot;;

```

### C/C++字符串指针的各种形式

参考：https://blog.csdn.net/cy_cai/article/details/38267039

  1. char c[]="hello"
是动态的，局部数据，存储在栈区，所在函数结束后编译器自动销毁。
若是在函数中，返回后的结果是不确定的且不安全，随时都有被回收的可能
c[0] = 't'; // 可行

  2. char * c = "hello"
全局数据，在静态存储区域。
*c = 't'; // false

  3. static char str1[] = "hello";
通过static开辟一段静态存储空间

### 关于char* p = "hello" 和 const char* p = "hello"

char* p = "hello"，新版本VS编译C++会报错：“初始化”: 无法从“const char [6]”转换为“char *”
因为字符串是静态的，存在静态/全局区域，而char *p的声明，意味着他为动态的，分配在栈区。

在写代码常常都会写char * p ="hello";这样的代码，虽然不是错误，但却不建议这样用。应该加const修饰。这句话背后的内涵是什么？下面就刨根问底一下：）这个行为在不同的c和c++的编译器上有会不同的行为，应该说char *a = "hello world";这种写法不能算错误的写法，所以c编译器不报错也不警告。早期的K&C认 为这是完全合法的，但从K&C第二版标准开始就明确指出“修改string literal的结果是未定义的，字符串并不总是可修改的，可能会放在只读内存区域“。从C89开始，这个问题有了更明确的规定。char _a = "hello world"；定义a是一种字符指针类并使用指定的字符数组（类型为array of char)“hello world"初始化，如果试图修改数组的内容行为将是未定义的。关键的解释就在"未定义“这个解释上，实际上未定义不是错误，它在这里表示代码不可移值。 所以在c89和c99规范的”公共扩展“部分有如下规则：String literals是可修改的，此时指向另外一个内容完全相同的对象。在c++中则有区别，c++2003标准规定string literal是由const字符数组构成的（array of n const char）,所以Ｃ＋＋明确了string literal是不可修改的。C++没有规定所有内容相同的string literal会指向同一个对象（相同的内容指向唯一的对象），这是由编译器实现决定的，同时指出了试图修改string literal的行为是未定义的。为了兼容C，所以不加const 的char_依然是可用的，但通常编译器会给出警告。最后Ｃ＋＋标准明确规定不赞成这样做（deprecated）。 修饰为deprecated表示将 来不再支持这个特性。

* * *

参考：https://blog.csdn.net/u011217649/article/details/52853059

## Getmemory函数详解--内存操作的理解

### 案例一

```cpp
string str1 = &quot;test&quot;;
string str2 = &quot;test&quot;;

```

> **分析:程序崩溃.**
>  str初始化并且赋值为NULL（即0）。
>  调用GetMemory函数，将该值（0）copy到实参p上，此时p的值为0；
>  p = (char *)malloc(100); 分配空间后，将对应的地址值赋给指针p，此时str值任为0，不受影响。
>  因此执行GetMemory之后，p得到新分配的空间地址，str依然为NULL；
>  问题一：strcpy(str, "hello world");将使程序崩溃。
>  问题二：局部变量存在栈区，malloc()分配的空间在堆区。执行GetMemory后，没有对p指向的堆中的内存进行回收free()，而局部变量p在函数执行完毕之后有编译器自动回收空间。

**我的实验：**

```cpp
string str1 = &quot;test&quot;;
string str2 = &quot;test&quot;;

```

声明一个指针，指针作为局部变量，存放在 **栈** 中，没有分配空间的情况下，默认初始化为一个地址。
NULL即为0值，将NULL赋值给str，其地址值为0
malloc分配空间：在 **堆** 上分配相应大小的空间，并把该空间的地址值赋值给 **栈** 上的指针str。
此时，内存分配情况： **栈** 上有一指针str，其值（即地址）指向堆中的一块儿大小为100字节的空间。

#### 修改：

```cpp
string str1 = &quot;test&quot;;
string str2 = &quot;test&quot;;

```

### 案例二

```cpp
string str1 = &quot;test&quot;;
string str2 = &quot;test&quot;;

```

分析：
char p[] = "hello world"; 该字符串属于局部数据，存储在栈区，函数运行完后自动销毁。
p指向“栈内存”，GetMemory 返回的是指向“栈内存”的指针，调用结束后栈内存释放，该指针的地址不是 NULL，但其原来的内容已经被清除，新内容不可知。
该程序会造成内存泄露，该栈区可能用作其他用途，存储其他内容。
