c++菜鸡求助 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
superhxnju
V2EX    C

c++菜鸡求助

  •  
  •   superhxnju 2015-11-03 21:42:40 +08:00 2211 次点击
    这是一个创建于 3681 天前的主题,其中的信息可能已经有所发展或是发生改变。

    代码

    #include <iostream> using namespace std; struct A{ int a; }; A & clone(A & a) { A * p; *p = a; cout << "p addr" << p << endl; return *p; } int main() { A a = A{3}; A & r = a; cout << "r addr" lt;< &r << endl; A & v = clone(r); cout << "v addr" << &v << endl; cout << a.a << " " << v.a << endl; v.a = 2; cout << a.a << " " << v.a << endl; delete &v; return 0; } 

    输出

    r addr0x7fff5514c938 p addr0x7fff78e62300 v addr0x7fff78e62300 3 3 3 2 a.out(22733,0x7fff77e0a000) malloc: *** error for object 0x7fff78e62300: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug Abort trap: 6 

    参考书目: C++ Primer Plus 6th > 8 Adventure in Functions > Reference Variables(page 400 , pdf 中的 415 页)

    A call to clone() conceals the call to new, making it simpler to forget to use delete later.

    Alt text

    疑问:
    - 函数 clone 中是否在堆中新分配了内存给*p?(个人认为不是,根据地址来看,地址属于栈)
    - 为什么书中写到是隐式调用了 new ,但是当 delete 的时候出现pointer being freed was not allocated的错误?


    环境
    - mac
    - g++
    - c++11

    10 条回复    2015-11-04 09:38:38 +08:00
    colatin
        1
    colatin  
       2015-11-03 21:53:46 +08:00
    建议把 c 的指针学好先。
    A *p; *p = a;
    这里的 p 就是个野指针。*p=a 相当于在一个不知道什么地方的地方写了一个值。
    superhxnju
        2
    superhxnju  
    OP
       2015-11-03 21:59:46 +08:00
    @colatin 大概知道是个野指针,但就是书看到这里的时候很困惑。书里面的这段是我理解有误。。。还是就是有问题?
    Ethaniz
        3
    Ethaniz  
       2015-11-03 22:00:41 +08:00
    没听说过 clone 会隐式调用 new 呢,你这里的情况是:在 clone 中声明了一个栈变量,类型是个指针,指向地址随机,然后把这个指针指向的地址赋上了 a 的值,然后又返回了这个指针指向的值的引用。函数调用结束,该指针消失。自始至终没有向堆申请任何空间,所以导致 delete 失败。
    theoractice
        4
    theoractice  
       2015-11-03 22:20:03 +08:00
    http://book.douban.com/review/5472087/
    这书是瞎写的吧。

    Accelerated C++
    Effective C++
    More Effective C++
    www.cplusplus.com/reference/
    看这些足够了。
    superhxnju
        5
    superhxnju  
    OP
       2015-11-03 22:22:23 +08:00 via iPhone
    @theoractice 看的是 c++ primer plus ,重拾一下 c++
    superhxnju
        6
    superhxnju  
    OP
       2015-11-03 22:24:36 +08:00 via iPhone
    @theoractice 看看基础就行
    znoodl
        7
    znoodl  
       2015-11-03 22:43:09 +08:00 via iPhone
    经典的不是 c++ primer 吗? 不带 plus ,不是一个作者,书里有 delete 的例子吗
    superhxnju
        8
    superhxnju  
    OP
       2015-11-03 22:54:33 +08:00 via iPhone
    @znoodl 被名字给欺骗了
    SYP
        9
    SYP  
       2015-11-03 23:25:48 +08:00
    这样的代码这本书还说的一本正经,还是放弃掉吧。
    yangyanggnu
        10
    yangyanggnu  
       2015-11-04 09:38:38 +08:00
    基本上,这,是作者的疏忽,但不能因此完全否定它的价值。





    ==============================================
    ***《 C++ Primer Plus (第 6 版)中文版》 勘误表***
    联系: [email protected]
    时间: 2013-9-24
    ==============================================

    P268
    错误: free_throws * pt;
    修正: free_throws * pt = new free_throws;

    P291
    错误:在这两个模板函数中, recycle<blot *>(blot *) 被认为是更具体的
    修正:在这两个模板函数中, recycle<blot>(blot *) 被认为是更具体的

    P337
    错误: static const LIMIT = 25;
    修正: static const unsigned LIMIT = 25;

    P386
    错误: t4 = t1 + t2 + t3 先转换为 t4 = t1.operator+(t2 + t3) 再转换为 t4 = t1.operator+(t2.operator+(t3))
    修正: t4 = t1 + t2 + t3 先转换为 t4 = t1.operator+(t2) + t3 再转换为 t4 = t1.operator+(t2).operator+(t3)

    P387
    错误:.*:成员指针运算符
    修正:->:成员指针运算符

    P428
    错误: String boston("Boston");
    修正: StringBad boston("Boston");

    P431
    错误:然后程序使用重载运算符>>列出了这些对象
    修正:然后程序使用重载运算符<<列出了这些对象

    P439
    错误:最简单的办法是使用标准的 trcmp()函数
    修正:最简单的办法是使用标准的 strcmp()函数

    P440
    错误: means.operator[][0] = 'r';
    修正: means.operator[](0) = 'r';

    P439
    错误:因为内置的>运算符返回的是一个布尔值
    修正:因为内置的<运算符返回的是一个布尔值

    P478
    错误: Cow(const Cow c& );
    修正: Cow(const Cow & c);

    P478
    错误:提供一个 Stringlow()成员函数
    修正:提供一个 stringlow()成员函数

    P478
    错误:提供 String()成员函数
    修正:提供 stringup()成员函数

    P505
    错误: 这意味着,即使基类不需要显式析构函数提供服务,也不应该依赖于默认构造函数
    修正: 这意味着,即使基类不需要显式析构函数提供服务,也不应该依赖于默认构造析构

    P508
    错误:半长轴
    修正:长半轴

    P510
    错误: void Move(int nx, ny) = 0
    修正: virtual void Move(int nx, ny) = 0

    P525
    错误:
    Star::Star double() {...}
    Star::Star const char * () {...}
    修正:
    Star::operator double() {...}
    Star::operator const char * () {...}

    P529
    错误:派生类的有元函数
    修正:派生类的友元函数

    P532
    错误: Cd(char * s1, char * s2, int n, double x);
    修正: Cd(const char * s1, const char * s2, int n, double x);

    P532
    错误:派生出一个 Classic 类,并添加一组 char 成员
    修正:派生出一个 Classic 类,并添加一个 char 数组成员

    P532
    错误: copy.Report()
    修正: copy.Report();

    P535
    错误:所有元素度被初始化为指定值的数组
    修正:所有元素都被初始化为指定值的数组

    P544
    错误:例如,在类声明中提出可以使用 average()函数。和包含一样,要实现这样的目的,可以在公有 Student::average()函数中使用私有 Student::Average()函数。
    修正:例如,对于类 Student 需要提供的 Average()函数,与包含版本一样,私有继承版本同样可以借用 valarray 的 size()和 sum()方法来实现。

    P549
    错误:和私有私有继承一样
    修正:和私有继承一样

    P551
    错误:这里使用两个独立的派生使基类( Worker )被继承
    修正:从基类( Worker )继承出两个独立的派生类

    P555
    错误:
    Enter waiter's name: Waldo Dropmaster
    ...
    Enter singer's name: Sylvie Sirenne
    修正:
    Enter worker's name: Waldo Dropmaster
    ...
    Enter worker's name: Sylvie Sirenne

    P573
    错误:只有一个 pop 变量
    修正:只有一个 po 变量

    P583
    错误: template <> class SortedArray<const char char*>
    修正: template <> class SortedArray<const char*>

    P656
    错误: string(const string & str, string size_type pos, size_type n = npos)
    修正: string(const string & str, size_type pos, size_type n = npos)

    P729
    错误:将 li 重置为排序的 vi0 的内容
    袖子:将 li 重置为未排序的 vi0 的内容

    P773
    错误: ofstream fout();
    修正: ofstream fout;

    P794
    错误: Store 的构造函数应接受一个指定 ifstream 对象的参数
    修正: Store 的构造函数应接受一个指定 ofstream 对象的参数

    P835
    错误:*pt = ai[i];
    修正:*pt = ar[i];
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5207 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 09:12 PVG 17:12 LAX 01:12 JFK 04:12
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86