简体   繁体   中英

Strange behavior with printing a vector of structs

I want to print the values of a vector of structs to stdout.

The struct is defined as follows:

typedef struct CallStackEntry {
    DWORD64 base_address;
    DWORD64 return_address;
    char* file_name;
    char* symbol_name;
    DWORD line_number;

    CallStackEntry(DWORD64 ba, DWORD64 ra, char* f_name, char* s_name, DWORD ln) : 
                        base_address(ba), return_address(ra), file_name(new char[strlen(f_name)+1]), symbol_name(new char[strlen(s_name)+1]), line_number(ln)  
    {
        memcpy(file_name,f_name, strlen(f_name)+1);
        memcpy(symbol_name,s_name,strlen(s_name)+1);
    }

    } CS;

The following code works for printing:

void debuglib::StdOutLogger::logg(std::vector<CS> ces) {
    std::vector<CS>::iterator itr;
    for ( itr = ces.begin(); itr < ces.end(); ++itr )
    {       
        //printf("%08x", itr->return_address);
        printf("%s() called\nBaseaddress: 0x%08x\n", itr->symbol_name, itr->base_address);
        printf("Returnaddress: 0x08%x\n", itr->return_address);
        printf("In File: %s (Line: %d)\n\n", itr->file_name, itr->line_number);
    }
}

This code, however, does not work:

for ( itr = ces.begin(); itr < ces.end(); ++itr ) { 
    printf("%s() called\nBaseaddress: 0x%08x\nReturnaddress: 0x%08x\nInFile:%s (Line: %d)\n\n", itr->symbol_name, itr->base_address, itr->return_address, itr->file_name, itr->line_number);
}

In the second code list, filenumber and return_address is always 0 and filename gives me some cryptic characters.

Anyone have an idea what could cause this problem?

Well more likely than not the first one only appears to work. I suspect what's happening is that your %x to print the address is actually being passed a 64-bit pointer (are you compiling a 64-bit binary?). Then when you do it in separate calls it appears fine and prints 32 bits out of the address. When you run it all together printf gets confused because you lied about the amount of space used by each member.

g++ will warn at -Wall if you try to do this.

The C++ way to solve this is to use iostreams. Type-safe and easy.

If you want the C way with printf you'll probably want to use %lx instead, and make sure you cast your pointer to long so the type always lines up.

Without seeing the definition of the CS struct, and without knowing about your C++ compiler and ABI settings, it's difficult to say for sure.

But the likeliest explanation is that you have a size issue. For example, I suspect that itr->base_address is a 64-bit variable but %08x is expecting a 32-bit variable. You probably need to use %08lx instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM