我的理解是,在 C 和 C++ 中,通过调用创建一个字符数组:
char *s = "hello";
实际上创建了两个对象:一个在静态空间中创建的只读字符数组,这意味着它在程序的整个持续时间内都存在,以及一个指向该内存的指针。指针是其作用域的局部变量,然后消失。
我的问题是当指针死亡时数组会发生什么?如果我在函数内部执行上面的代码,这是否意味着退出函数后出现内存泄漏?
我的理解是,在 C 和 C++ 中,通过调用创建一个字符数组:
char *s = "hello";
实际上创建了两个对象:一个在静态空间中创建的只读字符数组,这意味着它在程序的整个持续时间内都存在,以及一个指向该内存的指针。指针是其作用域的局部变量,然后消失。
我的问题是当指针死亡时数组会发生什么?如果我在函数内部执行上面的代码,这是否意味着退出函数后出现内存泄漏?
它在整个程序期间都存在
确切地说,正式它具有static
存储期限。
当指针死亡时数组会发生什么?
没有。
如果我在函数内部执行上面的代码,这是否意味着退出函数后出现内存泄漏?
不,因为(1)。(该数组仅在程序退出时“释放”。)
不,没有泄漏。
文字字符串存储在程序的数据部分中,该部分通常加载到只读内存页中。所有等效的字符串文字通常都指向相同的内存位置——它是一个单例。
char const *a = "hello";
char const *b = "hello";
printf("%p %p\n", a, b);
这应该为两个指针显示相同的值,并且对同一函数的连续调用也应该打印相同的值。
(注意,你应该声明这样的变量char const *
——指向常量字符的指针——因为数据是共享的。通过指针修改字符串文字是未定义的行为。如果内存页面是只读的,充其量你会崩溃你的程序,最坏的情况是,您将更改整个程序中该字符串文字的每次出现的值。)
const char* s = "你好"; 是代码(程序)的一部分 - 因此一个常量永远不会改变(除非你有一些讨厌的机制在运行时改变代码)
我的问题是当指针死亡时数组会发生什么?如果我在函数内部执行上面的代码,这是否意味着退出函数后出现内存泄漏?
不,不会有内存泄漏,当指针死亡时数组也不会发生任何事情。
只有通过动态分配,内存泄漏才可能发生malloc()
。当你成为malloc()
某事时,你必须free()
稍后再做。如果你不这样做,就会有内存泄漏。在你的情况下,这是一个“静态分配”:这个内存空间的分配和释放将被自动释放,你不必处理它。
这是否意味着退出函数后出现内存泄漏?
不,没有内存泄漏,字符串文字具有静态持续时间,并且在程序完成后将被释放。引用C++ 草案标准部分2.14.5 String literals
小节8
:
普通字符串文字和 UTF-8 字符串文字也称为窄字符串文字。窄字符串文字的类型为“n const char 数组”,其中 n 是字符串的大小,定义如下,并且具有静态存储持续时间
部分3.7.1 Static storage duration
说:
[...] 这些实体的存储将持续到程序的持续时间
注意在 C++ 中,这一行:
char *s = "hello";
使用不推荐使用的转换有关更多详细信息,请参阅 C++ 警告:不推荐使用从字符串常量到 'char*' [-Wwrite-strings]的转换。
正确的方法如下:
const char *s = "hello";
如果你使用 malloc 或 new,你只需要释放
编辑:
char* string = "一个字符串"; 内存分配是静态的,不是好的做法(如果它是常量,则声明应该是 const char*),因为当函数结束时它在堆栈中,它应该与其余的局部变量和参数一起被销毁。当您为变量分配内存时,您需要使用特定的 malloc/free 和 new/delete: char *string = new char[64]; --> 删除字符串;char *string = malloc(sizeof(char) * 64); --> 自由(字符串);//这不是最佳实践,除非你必须使用 C