【问题标题】:c++ pointer to function and void pointers iteraction resulting in wierd thingsc++ 指向函数的指针和 void 指针交互导致奇怪的事情
【发布时间】:2017-03-12 02:59:45
【问题描述】:

我正在家里做一个关于遗传算法的小项目。但我试图使其通用,所以我使用函数指针和空指针。但我认为这可能会造成一些问题。

项目这一部分的主要目标是获取一个指向函数的指针,该函数返回一个特定的结构。包含 void 指针的结构 当我试图查看它所指向的值时,它也不太正确。我怀疑这两者之间的交互可能会给我带来一些问题。

详情:

结构:

struct  dna_s{
    int         size;
    void        *dna;
};

population 是一个包含进程所有总体的类。此外,它还包含两个函数,init_func 和 fitter_func 都是函数的指针。

指向函数定义的指针:

typedef dna_s   (*init_func_t)();
typedef int     (*fitter_func_t)(dna_s);

人口等级:

class   population{
    private:
        //  Parameters
        int         population_size;
        node        *pop_nodes;

        //  Functions
        init_func_t     init_func;
        fitter_func_t   fitter_func;
    public:
        population(int  pop_size,init_func_t initialization_func){
            //  Insert parameters into vars.
            this->population_size   = pop_size;
            this->init_func         = initialization_func;

            //  Create new node array.
            this->pop_nodes         = new node[this->population_size];

            for(int i = 0;i < this->population_size; i++){
                dna_s   curr_dna        = this->init_func();
                char *s                = static_cast<char*>(curr_dna.dna);
                cout << s << endl;
                this->pop_nodes[i].update_dna(curr_dna);
            }
        }
};

你可以看到在构造函数中我插入了一个指向函数的指针,init_func。这个函数正在生成随机词。

init_func:

dna_s   init_func(){
    string alphanum = "0123456789!@#$%^&*ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    char        init_s[STRING_SIZE+1]   = {};
    dna_s       dna;

    //  Generate String
    for(int i = 0; i < STRING_SIZE; i++){
        init_s[i]   = alphanum[rand() % alphanum.size()];
    }

    cout    << "-->" << init_s << endl;

    //  Insert into struct.
    dna.size        = STRING_SIZE;
    dna.dna         = static_cast<void*>(&init_s);

    //  Return it
    return dna;
}

main 函数没那么有趣,但可能有关联:

int main(){
    //  Init srand
    srand(time(0));

    //  Parameters
    int         population_size     = 10;
    population  pop(population_size, init_func);
}

现在是有趣的部分,有什么问题? 在 init_func 中 cout 打印:

-->e%wfF

这一切都很好 但在人口类中,cout 打印:

e%Ω²(

奇怪的是前 2 个字符总是相同的,但其他 3 个字符总是这个字符串 Ω²(. 示例:

-->XaYN7
XaΩ²(
-->oBK9Q
oBΩ²(
-->lf!KF
lfΩ²(
-->RZqMm
RZΩ²(
-->oNhMC
oNΩ²(
-->EGB6m
EGΩ²(
-->osafQ
osΩ²(
-->3#NQt
3#Ω²(
-->D62l0
D6Ω²(
-->tV@mu
tVΩ²(

【问题讨论】:

  • 您使用指针有什么特别的原因(以这种方式具体而且根本没有)? C ++ 11 引入了std::function,它比你尝试做的更容易和更安全,我真的不明白你为什么在你的结构中使用void*
  • 它不需要真正的答案。您的问题是您正在返回一个指向堆栈上变量的指针,然后该变量会被其他内容覆盖。您需要在堆上分配一个缓冲区,使用 new char[] 或更好的方法,但只需使用 std::vector 等通用容器来保存二进制数据。
  • @UnholySheep std::function 是一种胖类型,它可以做的比你通常需要的要多得多,但要付出一定的代价。这不是一个很好的默认值
  • @tyranid 你说得对,我没想到谢谢。

标签: c++ struct function-pointers void-pointers


【解决方案1】:

您的代码存在一些生命周期问题。在你的 dna_S 结构中:

    void        *dna;

这是一个指针,它指向一个存在于别处的对象。然后,在你的 init_func 中:

dna_s   init_func(){
    ...
    char        init_s[STRING_SIZE+1]   = {};
    dna_s       dna;
    ...
    dna.dna         = static_cast<void*>(&init_s);
    ...
    return dna;
}

init_s 是一个存在于init_func 中的变量,你让dna 指向那个变量然后离开函数。 init_s 此时不再存在,dnapopulation 构造函数获取它时指向无用处,导致未定义的行为。

您可以通过使用new char[] 分配内存来解决此问题,就像您为pop_nodes 所做的那样,但您有责任在不再使用时删除该内存。

【讨论】:

    猜你喜欢
    • 2018-04-19
    • 1970-01-01
    • 1970-01-01
    • 2015-01-04
    • 1970-01-01
    • 1970-01-01
    • 2010-09-29
    • 2011-04-26
    • 1970-01-01
    相关资源
    最近更新 更多