【问题标题】:Identifying error that is causing "non-POD type 'class segment' "识别导致“非 POD 类型‘类段’”的错误
【发布时间】:2012-07-23 02:21:49
【问题描述】:

发生错误的代码部分:

int disk::access (const char fname[]){

    int char_count=77;
    int actual_count=0; //just to pass the tests.
    char c;

    cout << "the file name is " << fname << ", and the mode is " << mode << endl;
    if(strcmp(mode, "w")==0){
        for (int i = 0; i < size; i++) {
            //cout << "sgm to be written is " << sgm[i];
            fp=fopen(fname, "w");
            fprintf(fp, "%s\n",sgm[i]);
         }
        fclose(fp);
    }       
    if(strcmp(mode,"a")==0){
        fp=fopen(fname, "a");
        fprintf(fp, "%s\n", sgm);
        fclose(fp);
    }

    fp=fopen(fname, "r");

    do{
        c=fgetc(fp);
        if(c!=' ' && c!='\n')
        actual_count++; 
     }while(c!=EOF);
    fclose(fp);


    return actual_count;        
}

我的错误:

disk.cpp:在成员函数'int disk::access(const char*)'中:

disk.cpp:67:警告:不能传递非 POD 类型的对象 'class 通过'...'分割';调用将在运行时中止

编辑第 67 行是:fprintf(fp, "%s\n",sgm[i]);

编辑 SGM:

cpp 代码:

disk::disk(int num_of_segments, const char* temp_mode){

    size=num_of_segments;
    sgm = new segment[size];  //initializes num_of_segments in a disk

    count=0;        
    if(strcmp(mode, "w")!=0||strcmp(mode, "a")!=0){
        strcpy(mode, "w");
    }

}

disk::disk(){

    sgm = new segment[20]; //initialize 20 segments in a disk
    size=20;  //keeps track of how many are initialized
    count=0;  //keeps track of how many are added
    strcpy(mode, "w"); //initialize disk access mode to w


}

标题代码:

class disk {
    private:
        int size, count; //to keep a track of number of segments 
        char mode [2]; //a for append and w for write 
        segment* sgm;
        FILE *fp;

    public:
        disk(int num_of_segments, const char *temp_mode);
        disk();
        ~disk();
        const char* get_mode( ) const;
        segment get_segment(int pos) const;
        int get_segment_count( ) const;
        const segment* get_all_segments( ) const;
        int access(const char fname[ ]);
        disk& operator+=(const segment &rhs);
        disk& operator=(const disk &dk);
};

我以前从未遇到过这样的警告。我做了一些搜索,从我收集到的 POD 中是“普通的旧数据,它是一个没有构造函数、析构函数和虚拟成员函数的结构”。 ——格雷格·休吉尔

所以如果我理解正确,我的错误是我确实有构造函数或析构函数和/或虚拟成员函数,因为它不是 POD?

我想我只是让自己感到困惑,我不知道如何解决这个错误,甚至不知道问题发生在哪里。

欢迎所有建议并非常感谢,

谢谢。

【问题讨论】:

  • 我猜fprintf 中的一个是sgm[i]sgm
  • for (...) { fp = fopen(...); } fclose(fp); 如果循环迭代不止一次,则您正在泄漏文件句柄(您似乎一遍又一遍地重新打开和关闭同一个文件:有什么特别的原因吗?)。此外,对fopen 的调用可能会失败:您必须在使用返回值之前检查它是否成功。
  • 那是什么类型的?您可以编辑您的问题并提供sgm 的声明吗?谢谢
  • 您正在打开 N 个文件句柄(循环中每次迭代一个)并关闭 1 个文件句柄(循环结束后)。如果 N > 1,您打开的文件句柄将多于关闭的文件句柄。那些文件句柄被泄露了。对于您从fopen 获得的每个句柄,您必须调用fclose 来关闭它。
  • 您不能将非 POD 类型(如 segment)传递给 fprintf 等可变参数函数:tycho.ws/blog/2010/06/variadic

标签: c++ std segments


【解决方案1】:

如果sgm 包含virtual 方法或者是classstruct,则您依赖于实现就行了:

fprintf(fp, "%s\n",sgm[i]);

使用%s,您是在告诉fprintf sgm[i]char*。如果sgm[i] 有虚函数,这很可能是错误的(因为vfptr)。如果该类型的成员布局没有将char* 作为第一个数据成员,这将再次为假。

【讨论】:

  • 感谢 Luchian,使用您为我的团队提供的信息很长时间以来,我们能够查明我们的问题并成功进入最终测试阶段。
【解决方案2】:

我冒险猜测一下,“segment”是一个结构或一个类,而您正试图将其打印为“%s”字符串。

您需要实现一个将段转换为字符串的函数。或打印段的各个本地字段。

例如如果你这样定义段

struct segment { char name[10]; int index; }

应该作为

print("%s:%d\n", seg.name, seg.index);

或作为

inline std::ostream& operator << (std::ostream& os, const struct segment& seg)
{
return os<<seg.name<<":"<<seg.index;
}

你的方法调用变成:

std::ostringstream os;
os<<seg;
std::string segStr = os.str();
printf("%s\n", segStr.c_str());

您也可以手动编写一个 toString() 类型的函数来获取一个段的字符串表示。

【讨论】:

  • 啊,我明白了,好吧,我会试一试。非常感谢莫哈普斯。当我得到一些结果时,我会回来。
  • 谢谢 Mohaps 这有助于解决我们的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-06
  • 2022-01-02
  • 2020-11-07
  • 2020-04-04
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
相关资源
最近更新 更多