为什么我的字符串赋值会导致分段错误?

时间:2011-08-30 13:14:37

标签: c++ string segmentation-fault unions

我试图消除seg错误的常见原因,例如解除引用空指针,但我很难过。在调试模式下,我的测试机器上没有出现此错误,但在我的生产机器上出现了版本编译。两者都设置为/ O0以消除这种可能性。当我注释掉字符串赋值时,seg错误消失了,现在我只需要了解发生了什么,这样我就可以修复它。

可能有更明显的东西,但另一个复杂因素是内核模式应用程序正在调用此代码,而我从供应商处获得的关于为系统编写安全代码的唯一指令是“每个需要任何功能的函数”从操作系统或必须等待来自操作系统的任何东西都不会工作“(逐字)。

union {
    REAL_T real[8];
    char   byte[64];
} fileName;

void transferFilenames () {
    string tempname;

    // This is from an api I must use, it retrieves values from NVRAM on
    // an accessory board.  Specifically it will return 8 REAL_T values
    // and store them starting at &filename.real[0], inp/outpArray are 
    // globals defined elsewhere.
    inpArray.I7_ARRAY.INDEX = 2903;
    inpArray.I7_ARRAY.LEN = 8;
    inpArray.I7_ARRAY.Z_PAR_PTR = &fileName.real[0];
    b_array ( READ_CYCLE_PARAMS, &status, &inpArray, &outpArray );

    // if status != 0, there was an error
    if ( status == 0 ) {
        // there is no guarantee of being null terminated
        fileName.byte[63] = 0;

        /* This test code didn't fix the problem
        int i;
        char myStr[64];
        for ( i = 0; i < 64; i++ )
            myStr[i] = fileName.byte[i];
        if ( myStr[0] != '\0' )
            string mystring( myStr ); // seg fault
        */
        tempname.assign( fileName.byte ); // Throws seg fault
        // tempname.assign( &fileName.byte[0] ); // try to be more explicit

        // controlBlock is a global class defined elsewhere
        controlBlock->setFileName ( tempname, ISINPUT);
    } else {
        controlBlock->setFileName( "BAD", ISINPUT );
    }
    return;
}

当我重载我的控制块以直接获取char * controlBlock->setFileName( &fileName.byte[0] )时,并完全删除了字符串赋值,分段错误消失了。所有重载都将char *分配给本地字符串并调用常规方法。

我在幕后失踪了什么?

1 个答案:

答案 0 :(得分:3)

问题可能不在tempname.assign()的调用中。流水线操作可能会导致错误地报告恶魔真正所处的位置。这句话让我觉得恶魔在别处:

  

当我重载我的控制块以直接获取char * controlBlock-&gt; setFileName(&amp; fileName.byte [0]),并完全删除了字符串赋值时,分段错误消失了。

您在一个案例中将std::string传递给setFileName,在另一个案例中传递char*。尝试替换

controlBlock->setFileName ( tempname, ISINPUT);

controlBlock->setFileName ( tempname.c_str(), ISINPUT);

<强>附录
问题可能在于使用std::string,句号。如果保留的尺寸太小,std::string::assign()会调用malloc。使保留的大小足够大可能也不起作用;这可能只是将malloc调用推送到构造函数中。使用动态分配内存的东西并不符合子句所有需要操作系统的任何功能,或者必须等待来自操作系统的任何功能

实际上,这个子句可能会排除在这台机器上使用大量的C ++库。关于分配和释放内存,C ++库非常松散,std::string做了很多。