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我的应用程序的任何点,因为程序需要每个分配的内存,直到它存在(这,AFAIK 无论如何都会使每个分配的内存无效?!)

那么,如果我从不释放一个被释放的对象,它怎么会被破坏呢?

该函数在此调用:

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)会返回一个指针的大小(可能是 4 或 8,具体取决于您的 CPU)。您使用sizeof的好像buf是一个数组,这与 C 中的指针实际上并不相同,尽管它们在某些情况下似乎可以互换。

而不是使用sizeof,您需要跟踪为 分配的最后大小,并在每次扩大缓冲区时buf添加到该大小。BUF_SIZE

您还应该考虑到该read操作返回的字符可能比BUF_SIZE每次调用返回的字符少得多,因此在每次迭代中执行realloconbuf可能是矫枉过正。不过,就正确性而言,这可能不会对您造成任何问题;它只会使用比它需要的更多的内存。

我会做一些更像下面的代码的事情。

#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 的内存 a 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 回答