开发者

How to pass pointer and pointer to a function?

I implement a function that acts like getline( .. ). So my initial approach is:

#include <cstdio>
#include <cstdlib>
#include <cstring>

void getstr( char*& str, unsigned len ) {
    char c;
    size_t i = 0;
    while( true ) {
        c = getchar(); // get a character from keyboard
        if( '\n' == c || EOF == c ) { // if encountering 'enter' or 'eof'
            *( str + i ) = '\0'; // put the null terminate
            break; // end while
        }
        *( str + i ) = c;
        if( i == len - 1 ) { // buffer full 
            len = len + len; // double the len 
            str = ( char* )realloc( str, len ); // reallocate memory
        }
        ++i;
    }
}

int main() {
    const unsigned DEFAULT_SIZE = 4;
    char* str = ( char* )malloc( DEFAULT_SIZE * sizeof( char ) );
    getstr( str, DEFAULT_SIZE );
    printf( str );
    free( str );
    return 0;
}

Then, I think I should switch to pure C instead of using half C/C++. So I change char*& to char**: Pointer to Pointer version ( crahsed )

#include <cstdio>
#include <cstdlib>
#include <cstring>

void getstr( char** str, unsigned len ) {
    char c;
    size_t i = 0;
    while( true ) {
 开发者_Go百科       c = getchar(); // get a character from keyboard
        if( '\n' == c || EOF == c ) { // if encountering 'enter' or 'eof'
            *( *str + i ) = '\0'; // put the null terminate
            break; // done input end while
        }
        *( *str + i ) = c;
        if( i == len - 1 ) { // buffer full 
            len = len + len; // double the len 
            *str = ( char* )realloc( str, len ); // reallocate memory
        }
        ++i;
    }
}

int main() {
    const unsigned DEFAULT_SIZE = 4;
    char* str = ( char* )malloc( DEFAULT_SIZE * sizeof( char ) );
    getstr( &str, DEFAULT_SIZE );
    printf( str );
    free( str );
    return 0;
} 

But this version crashed, ( access violation ). I tried run the debugger, but I could not find where it crashed. I'm running Visual Studio 2010 so could you guys show me how to fix it?

Another weird thing I've encountered is that, if I leave the "&" out, it only works with Visual Studio, but not g++. That is

void getstr( char* str, unsigned len ) 

From my understanding, whenever we use pointer to allocate or deallocate a block of memory, we actually modify where that pointer are pointing to. So I think we have to use either ** or *& to modify the pointer. However, because it run correctly in Visual Studio, is it just luck or it should be ok either way?


Then, I think I should switch to pure C instead of using half C/C++.

I suggest the other direction. Go full-blown C++.


Your pointer crash is probably in the realloc

*str = ( char* )realloc( str, len )

Should be

*str = ( char* )realloc( *str, len )

As Steve points out, your code leaks the original if realloc fails, so maybe change it to something like:

char* tmp = (char*) realloc(*str, len)
if (tmp) {
    *str = tmp
} else {
    // realloc failed.. sigh
} 


Well, running it in a debugger highlights this line

        *str = ( char* )realloc( str, len ); // reallocate memory

where there is a mismatch between str - the pointer to the variable - and *str - the pointer to the memory.

I'd be tempted to rewrite it so it returns the string, or zero on error, rather than having a void return and an in/out parameter ( like fgets does, which seems to be the function you're sort-of copying the behaviour of ). Or wrap such a function. That style doesn't let you get confused as you're only ever dealing with a pointer to char, rather than a pointer to pointer to char.

    char* getstr_impl ( char* str, unsigned len ) {...}

    void getstr( char** str, unsigned len ) {
        *str = getstr_impl ( *str, len );
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜