【问题标题】:memory disordered in simple c strtok_r test简单的 c strtok_r 测试中的内存混乱
【发布时间】:2016-03-18 08:27:22
【问题描述】:

我有以下简单的 c 程序:

struct MarketOrderBook
{
    double price ;
    int    volume ;
};

struct DataFeed
{
    char symbol[16] ; //tag 48
    char exchange[16] ;  //tag 207
    char yymm[8] ;  //tag 200
    int  totalvolumetraded ;  //tag 387
    double tradeprice ;
    int  tradevolume ;
    MarketOrderBook BidOrder[5] ;
    MarketOrderBook AskOrder[5] ;
} ;

#define DATAFEEDCNT 256
int dostrtok(char* buf,char* ptr[])
{
    int in=0 ;
    char *token ;
    char *rest = buf ;
    //char pipe[2]={0x01,0x00} ;
    char pipe[2]={'|',0x00} ;
    while((token=strtok_r(rest,pipe,&rest))!=NULL) {
        ptr[in] = token ;
        in++ ;
        if( in > DATAFEEDCNT )
            break ;
    } //while
    return in ;
} //dostrtok

#define PRICECLIENT_VALUE_SIZE 128

void DoGetTagAndValue( char *ptr,char* leftvar,char* rightval )
{
    int idx=-1,ileftidx=0,irightidx=0;
    int leftpartend=0 ;
    while( 1 ){
        idx++ ;
        if( ptr[idx] == 0x00 || ptr[idx] == 0x01 || ptr[idx] == '|' )
            break ;
        if( ptr[idx] == '=' ){
            leftpartend=1 ;
            continue;
        }
        if( leftpartend == 0 ){
            leftvar[ileftidx++] = ptr[idx] ;
        }
        if( leftpartend == 1 ){
            if( irightidx >= PRICECLIENT_VALUE_SIZE )
                break ;
            rightval[irightidx++] = ptr[idx] ;
        }
    } //while
}//DoGetTagAndValue

void DoDealIncomeData( int inum,char**ptr )
{
    char ArrLeftVar[258][8]={0} ;
    char ArrRightVal[258][PRICECLIENT_VALUE_SIZE]={0} ;

    for(int idx=0;idx<inum;idx++){
        char leftvar[8]={0} ;
        char rightval[PRICECLIENT_VALUE_SIZE]={0} ;
        DoGetTagAndValue( ptr[idx],leftvar,rightval ) ;
        printf("(%s)=(%s) ",leftvar,rightval);
        if( idx < 258 ){
            strcpy( ArrLeftVar[idx] , leftvar ) ;
            strcpy( ArrRightVal[idx] , rightval ) ;
        }
    } //for
    printf("\n");

    DataFeed datafeed ;
    printf("*******(%s)************\n",datafeed.symbol);

    return ;
}
int main(int argc, char **argv)
{
    char xyz[128]={0} ;

    sprintf(xyz,"%s","8=FIX.4.2|9=00073|35=A|49=ABCD|56=XYZ|34=1|52=20160318-07:40:32.956|108=30|98=0|10=197|");

    printf("xyz=(%s)\n",xyz);
    char* ptr[DATAFEEDCNT]={0} ;
    int inum = dostrtok(xyz,ptr) ;
    printf("inum=(%d)\n",inum);
    DoDealIncomeData(inum,ptr) ;

    while(1)
    {
        sleep( 5 ) ;
    } //while
} //main

然后我编译它: g++ --std=c++11 testx.cpp -o testx.exe 在 g++ 4.8.3 和结果中:

xyz=(8=FIX.4.2|9=00073|35=A|49=ABCD|56=XYZ|34=1|52=20160318-07:40:32.956|108=30|98=0|10=197|)

inum=(10)

(8)=(FIX.4.2) (9)=(00073) (35)=(A) (49)=(ABCD) (56)=(XYZ) (34)=(1) (52)=(20160318-07:40:32.956) (108)=(30) (98)=(0) (10)=(197) 

*******(197)************

我认为 datafeed.symbol 应该显示 NULL 字符串,但令我惊讶的是 就是显示197,说明本次测试记忆错乱了, 在我使用这个测试的另一种解决方案之前,我仍然很好奇 我做错了什么导致这一切发生?!

【问题讨论】:

  • 你说的是这条线printf("*******(%s)************\n",datafeed.symbol);

标签: c++ c pointers memory


【解决方案1】:

对于 cmets,您的问题是关于 printf("*******(%s)************\n",datafeed.symbol); 行中发生的事情

我们可以看到,datafeed 对象只是在上面一行中创建的,我们可以将整个代码缩短为这个示例:

#include <iostream>

struct MarketOrderBook
{
    double price;
    int    volume;
};

struct DataFeed
{
    char symbol[16]; //tag 48
    char exchange[16];  //tag 207
    char yymm[8];  //tag 200
    int  totalvolumetraded;  //tag 387
    double tradeprice;
    int  tradevolume;
    MarketOrderBook BidOrder[5];
    MarketOrderBook AskOrder[5];
};


int main()
{
    DataFeed datafeed;
    printf("*******(%s)************\n", datafeed.symbol);
}

我们可以把这个例子简化成这样:

#include <iostream>

struct DataFeed
{
    char symbol[16]; //tag 48
};


int main()
{
    DataFeed datafeed;
    printf("*******(%s)************\n", datafeed.symbol);
}

更进一步:

#include <iostream>

int main()
{
    char symbol[16];
    printf("*******(%s)************\n", datafeed.symbol);
}

因此,当您查看此代码时,您可以清楚地看到您正在调用未定义的行为,因为符号未初始化。

您的程序打印 "107" 只是因为您的 symbol 数组的内存中存在一些数据。

【讨论】:

    猜你喜欢
    • 2017-04-30
    • 2016-01-21
    • 2011-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-31
    相关资源
    最近更新 更多