{
  "schemaVersion": "0.11.0",
  "canonical": "https://www.pystone.net/notes/cpp-string-pointer-param-memory-allocation/",
  "atlas": "https://www.pystone.net/?node=cpp-string-pointer-param-memory-allocation#knowledge-atlas",
  "markdown": "https://www.pystone.net/notes/cpp-string-pointer-param-memory-allocation.md",
  "context": "https://www.pystone.net/notes/cpp-string-pointer-param-memory-allocation.context.json",
  "knowledgeVersion": "224c990773de.5fa8af6e39fa",
  "build": {
    "siteCommit": "224c990773de166d23a886306577dd90379529ce",
    "notesCommit": "5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a",
    "builtAt": "1970-01-01T00:00:00.000Z",
    "version": "224c990773de.5fa8af6e39fa"
  },
  "id": "note:cpp-string-pointer-param-memory-allocation",
  "slug": "cpp-string-pointer-param-memory-allocation",
  "title": "字符串指针作为参数与空间分配问题",
  "type": "note",
  "visibility": "public",
  "idStability": "rename-stable",
  "author": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "publisher": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "aliases": [],
  "summary": "字符串指针作为参数与空间分配问题",
  "contentRole": "unspecified",
  "isMoc": false,
  "mocRecognition": "none",
  "generated": false,
  "attribution": "unspecified",
  "domain": "10-计算机、信息技术与工程",
  "tags": [],
  "mocs": [],
  "contentHash": "de0499dfe8340cb70be7fd7374d38c567f06c726cfe8561d43abe67b0aacf0f5",
  "assets": [],
  "headings": [
    {
      "depth": 1,
      "text": "字符串指针作为参数与空间分配问题",
      "anchor": "字符串指针作为参数与空间分配问题",
      "citation": "https://www.pystone.net/notes/cpp-string-pointer-param-memory-allocation/#%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%8C%87%E9%92%88%E4%BD%9C%E4%B8%BA%E5%8F%82%E6%95%B0%E4%B8%8E%E7%A9%BA%E9%97%B4%E5%88%86%E9%85%8D%E9%97%AE%E9%A2%98"
    },
    {
      "depth": 2,
      "text": "小知识点：",
      "anchor": "小知识点",
      "citation": "https://www.pystone.net/notes/cpp-string-pointer-param-memory-allocation/#%E5%B0%8F%E7%9F%A5%E8%AF%86%E7%82%B9"
    },
    {
      "depth": 3,
      "text": "输出指针值",
      "anchor": "输出指针值",
      "citation": "https://www.pystone.net/notes/cpp-string-pointer-param-memory-allocation/#%E8%BE%93%E5%87%BA%E6%8C%87%E9%92%88%E5%80%BC"
    },
    {
      "depth": 3,
      "text": "C/C++字符串指针的各种形式",
      "anchor": "cc字符串指针的各种形式",
      "citation": "https://www.pystone.net/notes/cpp-string-pointer-param-memory-allocation/#cc%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%8C%87%E9%92%88%E7%9A%84%E5%90%84%E7%A7%8D%E5%BD%A2%E5%BC%8F"
    },
    {
      "depth": 3,
      "text": "关于char p = \"hello\" 和 const char p = \"hello\"",
      "anchor": "关于char-p-hello-和-const-char-p-hello",
      "citation": "https://www.pystone.net/notes/cpp-string-pointer-param-memory-allocation/#%E5%85%B3%E4%BA%8Echar-p-hello-%E5%92%8C-const-char-p-hello"
    },
    {
      "depth": 2,
      "text": "Getmemory函数详解--内存操作的理解",
      "anchor": "getmemory函数详解--内存操作的理解",
      "citation": "https://www.pystone.net/notes/cpp-string-pointer-param-memory-allocation/#getmemory%E5%87%BD%E6%95%B0%E8%AF%A6%E8%A7%A3--%E5%86%85%E5%AD%98%E6%93%8D%E4%BD%9C%E7%9A%84%E7%90%86%E8%A7%A3"
    },
    {
      "depth": 3,
      "text": "案例一",
      "anchor": "案例一",
      "citation": "https://www.pystone.net/notes/cpp-string-pointer-param-memory-allocation/#%E6%A1%88%E4%BE%8B%E4%B8%80"
    },
    {
      "depth": 4,
      "text": "修改：",
      "anchor": "修改",
      "citation": "https://www.pystone.net/notes/cpp-string-pointer-param-memory-allocation/#%E4%BF%AE%E6%94%B9"
    },
    {
      "depth": 3,
      "text": "案例二",
      "anchor": "案例二",
      "citation": "https://www.pystone.net/notes/cpp-string-pointer-param-memory-allocation/#%E6%A1%88%E4%BE%8B%E4%BA%8C"
    }
  ],
  "claims": [],
  "outgoing": [],
  "incoming": [
    {
      "id": "note:programming-languages-and-runtimes",
      "title": "编程语言与运行时",
      "url": "https://www.pystone.net/notes/programming-languages-and-runtimes/",
      "atlas": "https://www.pystone.net/?node=programming-languages-and-runtimes#knowledge-atlas",
      "label": "编程语言与运行时",
      "origin": "explicit",
      "humanReviewed": true,
      "context": "C++中的“字符串指针作为参数与空间分配问题”导航项",
      "citation": "https://www.pystone.net/notes/programming-languages-and-runtimes/#c"
    }
  ],
  "contentMarkdown": "# 字符串指针作为参数与空间分配问题\n\n﻿# 字符串指针作为参数与空间分配问题\n\n> 创建时间：2020/3/14 22:34\n\n## 小知识点：\n\n### 输出指针值\n\n>\n```cpp\nstring str1 = &quot;test&quot;;\nstring str2 = &quot;test&quot;;\n\n```\n\n### C/C++字符串指针的各种形式\n\n参考：https://blog.csdn.net/cy_cai/article/details/38267039\n\n  1. char c[]=\"hello\"\n是动态的，局部数据，存储在栈区，所在函数结束后编译器自动销毁。\n若是在函数中，返回后的结果是不确定的且不安全，随时都有被回收的可能\nc[0] = 't'; // 可行\n\n  2. char * c = \"hello\"\n全局数据，在静态存储区域。\n*c = 't'; // false\n\n  3. static char str1[] = \"hello\";\n通过static开辟一段静态存储空间\n\n### 关于char* p = \"hello\" 和 const char* p = \"hello\"\n\nchar* p = \"hello\"，新版本VS编译C++会报错：“初始化”: 无法从“const char [6]”转换为“char *”\n因为字符串是静态的，存在静态/全局区域，而char *p的声明，意味着他为动态的，分配在栈区。\n\n在写代码常常都会写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表示将 来不再支持这个特性。\n\n* * *\n\n参考：https://blog.csdn.net/u011217649/article/details/52853059\n\n## Getmemory函数详解--内存操作的理解\n\n### 案例一\n\n```cpp\nstring str1 = &quot;test&quot;;\nstring str2 = &quot;test&quot;;\n\n```\n\n> **分析:程序崩溃.**\n>  str初始化并且赋值为NULL（即0）。\n>  调用GetMemory函数，将该值（0）copy到实参p上，此时p的值为0；\n>  p = (char *)malloc(100); 分配空间后，将对应的地址值赋给指针p，此时str值任为0，不受影响。\n>  因此执行GetMemory之后，p得到新分配的空间地址，str依然为NULL；\n>  问题一：strcpy(str, \"hello world\");将使程序崩溃。\n>  问题二：局部变量存在栈区，malloc()分配的空间在堆区。执行GetMemory后，没有对p指向的堆中的内存进行回收free()，而局部变量p在函数执行完毕之后有编译器自动回收空间。\n\n**我的实验：**\n\n```cpp\nstring str1 = &quot;test&quot;;\nstring str2 = &quot;test&quot;;\n\n```\n\n声明一个指针，指针作为局部变量，存放在 **栈** 中，没有分配空间的情况下，默认初始化为一个地址。\nNULL即为0值，将NULL赋值给str，其地址值为0\nmalloc分配空间：在 **堆** 上分配相应大小的空间，并把该空间的地址值赋值给 **栈** 上的指针str。\n此时，内存分配情况： **栈** 上有一指针str，其值（即地址）指向堆中的一块儿大小为100字节的空间。\n\n#### 修改：\n\n```cpp\nstring str1 = &quot;test&quot;;\nstring str2 = &quot;test&quot;;\n\n```\n\n### 案例二\n\n```cpp\nstring str1 = &quot;test&quot;;\nstring str2 = &quot;test&quot;;\n\n```\n\n分析：\nchar p[] = \"hello world\"; 该字符串属于局部数据，存储在栈区，函数运行完后自动销毁。\np指向“栈内存”，GetMemory 返回的是指向“栈内存”的指针，调用结束后栈内存释放，该指针的地址不是 NULL，但其原来的内容已经被清除，新内容不可知。\n该程序会造成内存泄露，该栈区可能用作其他用途，存储其他内容。\n"
}
