2

Section of my code where error is occuring:

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;        
}

my error:

disk.cpp: In member function 'int disk::access(const char*)':

disk.cpp:67: warning: cannot pass objects of non-POD type 'class segment' through '...'; call will abort at runtime

EDIT line 67 is: fprintf(fp, "%s\n",sgm[i]);

EDIT SGM:

the cpp code:

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


}

the header code:

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);
};

I haven't come across a warning like this before. I did some searching and from what I gathered POD is "plain old data that is a struct without constructors, destructors and virtual members functions." -Greg Hewgill

So if I understood that correctly, my error is that I do have constructors or destructors and or virtual member functions because it is non-POD?

I think I'm just confusing myself, I'm not sure how to go about fixing this error or even pinpointing where the problem is occuring.

All suggestions are welcome and greatly appreciated,

thanks.

SorryEh
  • 900
  • 2
  • 15
  • 47
  • I'm guessing one of the `fprintf` with either `sgm[i]` or `sgm`. – chris Jul 24 '12 at 17:47
  • sorry i forgot to add that part in: Line 67 is: "fprintf(fp, "%s\n",sgm[i]);" – SorryEh Jul 24 '12 at 17:48
  • 2
    `for (...) { fp = fopen(...); } fclose(fp);` If the loop iterates more than once, you are leaking file handles (you seem to be reopening and closing the same file over and over again: is there any particular reason for this?). Also, the call to `fopen` may fail: you must check it for success before using the return value. – James McNellis Jul 24 '12 at 17:49
  • @JamesMcNellis What does it mean to "leak file handles" ? – SorryEh Jul 24 '12 at 17:54
  • @LuchianGrigore sgm initializes number of segments in a disk, the size is 20. And no sorry I didn't realize that knowing what sgm was would have been useful information. – SorryEh Jul 24 '12 at 17:55
  • 2
    So what's the type? Can you edit your question and provide the declaration of `sgm`? Thanks – Luchian Grigore Jul 24 '12 at 17:55
  • 2
    You are opening N file handles (one per iteration through the loop) and closing 1 file handle (after the loop finishes). If N > 1, you will have opened more file handles than you closed. Those file handles are leaked. For every handle you get from `fopen`, you must call `fclose` to close it. – James McNellis Jul 24 '12 at 17:58
  • @JamesMcNellis ohhh i see that makes perfect sense thank you, I'll get on that. – SorryEh Jul 24 '12 at 18:09
  • @LuchianGrigore i've updated the question. sgm is a pointer because the new is making space for the segment coming in, at least this was our intent (group work). I've included the header file as well. – SorryEh Jul 24 '12 at 18:11
  • 1
    You can't pass non-POD types, like `segment`, to variadic functions like fprintf: http://tycho.ws/blog/2010/06/variadic – Nate Kohl Jul 24 '12 at 18:17

2 Answers2

3

I'll venture a guess and say "segment" is a struct or a class and you're trying to print it as a "%s" string.

you need to either implement a function that converts segment to string. or print individual native fields of the segment.

e.g. if you defined segment like this

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

should be handled either as

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

or as

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

and your method call becomes:

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

you can also hand code a toString() type function to get a string representation of a segment.

mohaps
  • 1,010
  • 5
  • 10
1

If sgm contains virtual methods or is a class or struct, you're relying on the implementation on the line:

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

With %s you're telling fprintf that sgm[i] is a char*. If sgm[i] has virtual functions, this will most likely be false (because of the vfptr). If the member layout of the type doesn't put a char* as the first data member, this will, again, be false.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • thank you Luchian, using the information you have provided my group a long with mohaps we were able to pin point our problem and we managed to progress into our final test stage. – SorryEh Jul 30 '12 at 07:59