10

私は得る

malloc: *** error for object 0x1001012f8: incorrect checksum for freed object
        - object was probably modified after being freed.
        *** set a breakpoint in malloc_error_break to debug

次の関数のエラー:

char* substr(const char* source, const char* start, const char* end) {
    char *path_start, *path_end, *path;

    int path_len, needle_len = strlen(start);

    path_start = strcasestr(source, start);
    if (path_start != NULL) {
        path_start += needle_len;
        path_end = strcasestr(path_start, end);
        path_len = path_end - path_start;
        path = malloc(path_len + 1);
        strncpy(path, path_start, path_len);
        path[path_len] = '\0';
    } else {
        path = NULL;
    }

    return path;
}

どうすればこれを機能させることができますか?関数を書き直して、それを使用してメモリを割り当てると、path[path_len + 1]問題なく動作します。

今、私が理解していない部分はfree、プログラムが存在するまで、割り当てられたすべてのメモリがプログラムに必要になるため、アプリケーションのどの時点でも呼び出すことさえないということです(とにかく、割り当てられたすべてのメモリを無効にします?!)

では、オブジェクトを解放しないと、解放されたオブジェクトがどのように破損するのでしょうか?

この関数は次のように呼び出されます。

char *read_response(int sock) {
    int bytes_read;
    char *buf = (char*)malloc(BUF_SIZE);
    char *cur_position = buf;

    while ((bytes_read = read(sock, cur_position, BUF_SIZE)) > 0) {
        cur_position += bytes_read;
        buf = realloc(buf, sizeof(buf) + BUF_SIZE);
    }

    int status = atoi(substr(buf, "HTTP/1.0 ", " "));

がありますが、realloc使い方が間違っていますか? 完全なサーバー応答を読みたいので、反復ごとに再割り当てする必要がありますよね?

4

2 に答える 2

10

ではread_response、 が指すバッファの末尾を上書きしている可能性がありますbuf

問題は、buf がポインターであるため、ポインターsizeof(buf)のサイズを返すことです (CPU によっては、おそらく 4 または 8)。sizeof配列であるかのように使用していますがbuf、これは実際には C のポインターと同じではありませんが、一部のコンテキストでは互換性があるように見えます。

を使用する代わりに、sizeofに割り当てた最後のサイズを追跡し、バッファを拡大するたびにそれbufに追加する必要があります。BUF_SIZE

また、操作が各呼び出しreadよりもかなり少ない文字を返す可能性があることを考慮する必要があるため、各反復で onを実行するのはやり過ぎになる可能性があります。ただし、正確さに関してはおそらく問題はありません。必要以上のメモリを使用するだけです。BUF_SIZEreallocbuf

以下のコードのようなことをします。

#define MIN_BUF_SPACE_THRESHOLD (BUF_SIZE / 2)

char *read_response(int sock) {
    int bytes_read;
    char *buf = (char*)malloc(BUF_SIZE);
    int cur_position = 0;
    int space_left = BUF_SIZE;

    if (buf == NULL) {
        exit(1); /* or try to cope with out-of-memory situation */
    }

    while ((bytes_read = read(sock, buf + cur_position, space_left)) > 0) {
        cur_position += bytes_read;
        space_left -= bytes_read;
        if (space_left < MIN_BUF_SPACE_THRESHOLD) {
            buf = realloc(buf, cur_position + space_left + BUF_SIZE);
            if (buf == NULL) {
                exit(1); /* or try to cope with out-of-memory situation */
            }
            space_left += BUF_SIZE;
        }
    }

readこのバージョンには、呼び出しが数バイトのデータだけで戻ってきた場合に、より多くのスペースを割り当てようとしないという利点があります。

于 2012-07-12T18:59:07.740 に答える
6

この行

buf = realloc(buf, sizeof(buf) + BUF_SIZE);

間違っている。すべての再割り当ては同じサイズですBUF_SIZE + sizeof(char*)。次に、ソケットから読み取るときに未割り当てのメモリに書き込み、以前にfreed によってメモリを上書きしますrealloc

割り当てられたサイズを追跡する必要があります。

size_t current_buf_size = BUF_SIZE;
/* ... */
    char *temp = realloc(buf, current_buf_size + BUF_SIZE);
    if (temp == NULL) {
        /* die or repair */
    }
    buf = temp;
于 2012-07-12T18:53:50.807 に答える