如果没有从堆中为字符串文字分配内存,是否安全
Is it safe if memory is not allocated from heap for string literal?
class MyString
{
char* str;
public:
MyString(char* _str)
{
str = _str;
}
};
int main()
{
MyString obj1("hi"); // case 1
char str[] = "hi";
MyString obj2(str); // case 2
}
在这里,我没有从成员str的构造函数中的堆中分配内存。案例 1 和案例 2 都安全吗?如果没有,为什么?
一种情况下,它不安全,但不是因为内存的分配位置,而是因为"hi"
是const char*
类型(可能在 .text 或 .data 上谁知道(,并且 MyString
的构造器将其分配给 char*
类型的变量。如果有人试图通过str
修改字符串,就会发生未定义的行为。
第二种情况的问题在于,您的对象obj2
指向一个它没有所有权的字符串,无论它是堆栈还是堆。这不是一件可怕的事情,我已经看到了它的合法用途,但必须小心翼翼地完成。这个特定示例可以正常工作,因为对象和字符串都存在于堆栈中,并且因为它非常简单。
第一种情况是可以的,因为"hi"是一个静态字符串 - 一个全局常量。它的生存时间至少与 obj1 一样长(即使 obj1 是全局的或在堆上分配的(。
第二种情况可能不行,因为"hi 被复制到堆栈上的 str[] 中。
在这种特殊情况下,obj2 在 str 之前被销毁,所以没问题。如果您要返回 obj2 的副本,或者它本身被分配到堆上,那么这将是一个问题,因为它的寿命可能超过 str。
str 的数据([ 'h', 'i', '\0']( 在堆栈上 - 与局部变量相同。此内存仅在其保持在范围内时才有效 - 在这种情况下,直到 main(( 返回。由于 obj2 也在堆栈上,因此它本质上具有与 str 相同的生命周期,因此在这种情况下没有问题。更一般地说,您可以创建具有不同生存期的此对象的实例,例如"MyString *s = new MyString(str(;返回 s;"。现在,MyString 对象将比 str 活得更久,并且将继续指向 str 曾经导致未定义行为的内存。这是通常难以找到错误的常见来源。
- Win32编译器选项和内存分配
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 当需要超过16GB的连续内存时,内存分配失败
- 尝试摆脱任何堆内存分配
- 以下代码执行哪种内存分配(动态或静态)?
- 开放 CV 中的动态内存分配,用于视频处理
- 为什么类和 main() 函数中也有动态内存分配
- 使用 NTAllocateVirtualMemory 和 GetProcAddress 的内存分配问题不起作用
- C++:矢量分配器行为、内存分配和智能指针
- 介于 [固定数组] 和 [带内存分配的指针] 之间的性能
- Linux C++ 中的页面对齐内存分配
- 整数内存分配/释放
- 将内存分配返回值强制转换为 TYPE 数组
- C++程序什么都不做,但瓦尔格林德显示内存分配
- 给定特定内存地址的数组的动态内存分配
- 如何完成内存分配
- 我刚刚了解了C++中的动态内存分配
- 在先前调用 string::find 后添加内存分配和内存集会导致它返回 npos.为什么?
- 对于堆上的页面对齐内存分配是否有任何优化或不同的 API?
- 无法删除布尔动态内存分配