gpt4 book ai didi

c++ - 析构函数无法删除已分配的连续内存块

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:51:09 25 4
gpt4 key购买 nike

以下代码可以编译但在运行时会出现错误:

# include <iostream>
# include <string.h>

class A {
public:
A() {}
A ( int id, char * t_name ) {
_id = id ;
name = new char [ strlen (t_name) + 1 ] ;
strcpy ( name, t_name ) ;
}

char *name ;
int _id ;
~A() { delete [] name ;}
} ;

int main () {
A a ( 1, "123" ) ;
A b ;
b = a ;

std::cout << static_cast < const void * > ( a.name ) << std::endl ;
std::cout << static_cast < const void * > ( b.name ) << std::endl ;

b.name = "abc" ; // b.name is directed to a different memory block
std::cout << static_cast < const void * > ( a.name ) << std::endl ;
std::cout << static_cast < const void * > ( b.name ) << std::endl ;
std::cout << a.name << std::endl ;
std::cout << b.name << std::endl ;

return 0 ;
}

它的输出是这样的:

0x7ff87bc03200
0x7ff87bc03200
0x7ff87bc03200
0x10f9bcf64
123
abc
a.out(883,0x7fff7ee3d000) malloc: *** error for object 0x10f9bcf64:
pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6

我不明白为什么它说:

0x10f9bcf64: pointer being freed was not allocated

因为 b.name 显然指向 0x10f9bcf64,并且不再与 a 重叠!

我也想知道如何解决这个问题?谢谢!

最佳答案

您应该首先阅读有关 Rule of 3/5/0 的内容.你的陈述:

b = a;

违反了规则 3(如果您使用的是现代 C++,即 C++11 或更高版本,则为 5),因为您的类 A 有一个指针作为成员。

接下来,如果您考虑以下语句:

b.name = "abc";

您在这里影响的是您未使用 new 分配的静态字符数组。所以当你的析构函数试图删除它时:

~A() { delete []  name ;}

调用 delete[] 会产生错误。

一个简单的解决方案是将 name 声明为 std::string:

class A {
public:
A () {}
A ( int id, const std::string& t_name ) {
_id = id ;
name = t_name;
}

std::string name ;
int _id ;
} ;

int main () {
A a ( 1, "123" ) ;
A b ;
b = a ;

std::cout << static_cast < const void * > ( &a.name ) << std::endl ;
std::cout << static_cast < const void * > ( &b.name ) << std::endl ;

b.name = "abc" ; // b.name is directed to a different memory block
std::cout << static_cast < const void * > ( &a.name ) << std::endl ;
std::cout << static_cast < const void * > ( &b.name ) << std::endl ;
std::cout << a.name << std::endl ;
std::cout << b.name << std::endl ;

return 0 ;
}

由于 std::string 为您管理内存,您又回到了 0 规则的美妙世界。

关于c++ - 析构函数无法删除已分配的连续内存块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41286384/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com