简体   繁体   中英

Character pointer's address changing

I am confused about the const char pointer.

Here is the code:

int main()
{
    const char map[12][24];
    char fileName[] = "map1.txt";
    const char * mPtr;
    mPtr = map;


    printf( "%d %d \n", mPtr, map );

    load_map( fileName, map );

    printf( "%d %d \n", mPtr, map );


    return 0;
}

Here is the load_map() function code:

bool load_map( char * fileName, char * map )
{
    FILE * fptr;
    char c;
    int count = 0;

    fptr = fopen( fileName, "r" );

    if( fptr == NULL ) {
        printf( "Fail to read map \n" );
        return false;
    }

    do {

        c = fgetc( fptr );
        *( map + count++ ) = c;
        if ( count % 23 == 0 ) continue;
        *( map + count++ ) = ' ';


    } while( c != EOF );

    fclose( fptr );
}

My question is when execute

mPtr = map;

and they exactly with the same memory address, but after the load_map() function executed mptr 's value has changed.

But in that function, I do not reference mptr . What is happening?

I believe this is undefined behavior.

The map array is declared as const , but you write into it in the load_map() function, that's just wrong. Why is it const , when you obviously expect and intend to change it by loading data into it?

It's most likely because you write beyond the bounds of the arrays in map , so the data you write out of bounds spill over to the mPtr variable.

Also, the variable map in the main function is declared as an array of arrays, but the load_map expected it to be a char * (or a single-dimension array). I would be surprised if you didn't get an error or at least a warning about this.

You definitely should switch on all warning levels that your compiler provides. The following line

load_map( fileName, map );

is undefined behavior. Your are passing a pointer value that is of type char const(*)[24] to a function argument that expects a char* . These are completely different beast, so no wonder that the result of your executions is somewhat arbitrary.

Any decent modern compiler should have told you.

if ( count % 23 == 0 ) continue;

This test is wrong. You're storing a blank after 22 of every 23 characters, thus surely overwriting the array. It looks like what you really want is

     map[count++] = c;
     if ((count % 24) == 23) map[count++] = ' ';

And since your input array only has room for 12 groups of 24 chars, you ought to check to make sure that you don't go over ... this is just the sort of code that is a feast for hackers to exploit, to the tune of billions of dollars in losses.

You also have several other problems, as identified in other answers and comments, and a few that no one has mentioned ... for example, you check for EOF in the wrong place ... it makes no sense to read a char, store it in an array, then check to see if it was EOF. And it's undefined behavior (you have a great deal of that in this program) to read EOF into a char ... c needs to be an int .

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