尝试释放时出现堆错误

时间:2015-04-28 11:36:47

标签: c strcat

这闻起来像某种堆腐败,但我似乎无法找到它。 尝试运行string_utils_replace()时问题发生在free(tmp_for_free)上。该函数应该用"search"中的"replace"替换"string"的每一次出现。

char* string_utils_part_of_string(char *string, int from, int to)
{
    int size_to_allocate = to - from + 1;
    char *result = (char*)malloc(sizeof(char) * size_to_allocate);

    strncpy(result, string + from, to - from);
    result[size_to_allocate - 1] = '\0';

    return result;
}

char* string_utils_replace(char *search, char *replace, char *string)
{
    char *end, *result = string, *tmp_for_free = NULL;
    int before_replace, after_replace;
    int size_search = strlen(search);
    int size_replace = strlen(replace);
    int size_string, size_find;
    int first_time = 1;

    char *find = strstr(string, search);

    if (find == NULL)
        return string_utils_copy_string(string);

    while (find != NULL)
    {
        tmp_for_free = result;

        size_string = strlen(result);
        size_find = strlen(find);

        before_replace = size_string - size_find;
        after_replace = before_replace + size_replace;

        end = string_utils_part_of_string(result, after_replace, size_string);
        result = string_utils_part_of_string(result, 0, before_replace);
        strcat(result, replace);
        strcat(result, end);

        // no memory leaks, hooray!
        free(end);
        if (first_time == 0)
            free(tmp_for_free);

        size_string = strlen(result);
        find = strstr(result, search);
        first_time = 0;
    }

    return result;
}

任何想法?

2 个答案:

答案 0 :(得分:3)

根据strcat()的{​​{3}},

  

char *strcat(char *dest, const char *src);

     

[..] 并且dest字符串必须有足够的空间用于结果。如果dest不够大,程序行为是不可预测的;

string_utils_part_of_string()函数中,您没有为result分配足够的内存以便能够保存整个输入,之后,您尝试使用通过strcat()存储整个输入的相同指针。这会产生内存溢出,而后者会调用man page

注意:请malloc() Cpublic class ToDoModel implements Comparable<ToDoModel> { private String id; private Date taskDate; public String getId() { return id; } public void setId(String id) { this.id = id; } public Date getTaskDate() { return taskDate; } public void setTaskDate(Date taskDate) { this.taskDate = taskDate; } @Override public int compareTo(ToDoModel another) { return getTaskDate().compareTo(another.getTaskDate()); } } 中的家人返回undefined behaviour

答案 1 :(得分:1)

这里导致缓冲区溢出:

    result = string_utils_part_of_string(result, 0, before_replace);
    strcat(result, replace);
    strcat(result, end);

result分配了before_replace+1个字节,并从before_replace的开头和最后的string初始化为'\0'个字节。您无法将replaceend连接到此数组,它已经已满。

你的功能中的逻辑是错综复杂的。你应该简化它。例如,您应首先运行一个循环来计算findstring的出现次数,然后为结果分配一个缓冲区,然后运行第二个循环复制string的片段并复制replace

您还应该测试find是否为空字符串。 strstr()将始终找到空字符串,导致算法无休止地循环。