ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c-试图将父指针动态分配给函数内的子代会导致分段错误

2019-10-10 09:10:09  阅读:188  来源: 互联网

标签:c pointers segmentation-fault


我一直在努力理解多态性和指针,但是这个概念使我有些不解.幸运的是我有stackoverflow和google,所以我的大多数问题都可以轻松解决.但是,我已经尝试修复这个分割错误了好几个小时了,但是没有运气,我不确定发生了什么.我已经精简了所有内容以尝试了解问题所在,但我认为我缺少动态分配中的核心概念.

我将字符指针传递给函数初始化,是否不能在函数内部动态分配它?我的代码可以编译,但是在为(预期的)开关提供输入之后,就会出现分段错误,并且核心转储.

但是,如果我不使用函数初始化,而只在主函数中运行代码,则不会中断,并且zed已正确初始化为野蛮类型.

#include "character.h"//abstract class
#include "barbarian.h"//inherits character



void initialize(character *object){//gets the values for the object
                              //and lets user deem which type of object
    int x=0;
    cout<< "1. Barbarian."<<endl;
    cout<< "2. Gollum."<<endl;
    cout<< "3. Baba Yaga."<<endl;
    cout<< "4. Blue Men Group."<<endl;
    cout<< "5. Unicorn."<<endl;
    while(!(cin>>x)){
        cout<<"Input not valid."<<endl;
        cin.clear();
        cin.ignore(10000,'\n');
    }
    cout<<"Input is: "<<x<<endl;               //debug line
    object = new barbarian("conan");           //seg fault here
    //down here is a switch that was excluded for this question
 }

void die(character *kill){//is now kill
    delete kill;
}               //this should delete the character after it is used

int main(){
    srand(time(0));//used for roll functions in the parent class
    cout<<(-time(0))<<"seconds until 1970"<<endl;//debug makes sure srand is
                                            //doing what I want it to

    character* zed;  //zed = new barbarian("conan");//In main this works
    initialize(zed);
    //zed = new barbarian("conan"); This works
    (*zed).atkRoll();
    (*zed).defRoll();
    die(zed);
}

我希望能够传递一个字符指针,然后将其作为用户选择的类分配给堆,并在main调用的其他函数中使用它.我认为可以只传递指针并将其作为函数中的参数.然后,本地指针将指向与main指针相同的位置.随着函数作用域的关闭和“对象”的删除,则main中的指针应保持指向野蛮人的存储位置.这是无效的吗?如果可以,我该怎么办?
是否可以在不告知指针的情况下更改main中指针的类型?

我非常困惑>.<

解决方法:

我认为这应该像:

void initialize(character **object){
    /* ... */
    *object = new barbarian("conan");
}

否则,您不是在修改实际的指针,而是它的临时副本.您需要将指针传递给指针.然后,在main()中:

character* zed;
initialize(&zed);

最后一段中的问题说明:

您在main()中使用了字符* zed.这意味着,一个包含地址的指针变量(还没有有意义的地址,只是垃圾):

zed = 0x12345678

现在,您调用initialize(zed).在该函数中,有一个类型为“指向野蛮人的指针”的参数称为对象.它被初始化为zed的副本,即zed的值:

zed = 0x12345678
object = 0x12345678

现在调用object = new barbarian().分配内存并在对象中保存地址:

zed = 0x12345678
object = 0xABCDEF00

现在,initialize()退出.对象是临时的,并被销毁.剩下什么:

zed = 0x12345678 (garbage)
object doesn't exist

解决方法是我回答的开始.

我认为segfault应该出现在main()中,而不是在initialize()中.

(*zed).atkRoll();
(*zed).defRoll();

因为您在未初始化的指针上调用对象的方法,这些方法(据说)试图访问对象的字段.

也:

void die(character **kill){
    delete *kill; *kill == nullptr;
}

尽管无论如何,这种方法的想法对我来说似乎非常糟糕.

标签:c,pointers,segmentation-fault
来源: https://codeday.me/bug/20191010/1885713.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有