【问题标题】:Strange malloc crashing issues奇怪的 malloc 崩溃问题
【发布时间】:2015-10-16 10:26:15
【问题描述】:

dict[num] = malloc(INIT);

assert(dict != NULL);

其中 dict 是 char** ,INIT 是 10 [在崩溃时,dict** 重新分配了 80 个内存,这应该足以容纳大约 20 个字符串],在崩溃期间 num 是 15

我对 malloc where 有一个奇怪的情况

malloc(25) = 整个函数运行良好

malloc(17-24) = 断言错误 - 第 2 行

malloc(anything <=16) = 第 1 行崩溃

如果有帮助,dict[num] 应该包含 2 个字符、一个字母(或换行符)、一个数字和一个空字节。 dict[15] 恰好是 '\n0'。

为什么会这样?我认为您只需要分配与字符一样多的内存。

作为记录,我还有一个 memset(dict[num],'\0',INIT) 行出现在 malloc + assert 行之后。

EDIT = 这是整个功能 - 它应该是 LZ78 压缩器/编码器

char *factory(char *input,int max){
int j,k,match,subtractor=0;
char *x = malloc(INIT);

char **dict = malloc(10*sizeof(dict[0]));
int dict_size = INIT;
assert ( dict != NULL );

char *temp = malloc(INIT);
int temp_size = INIT;
assert ( temp != NULL );

char *factors = malloc(INIT);
assert ( factors != NULL );
char *tempstring = malloc(INIT);
int tempstr_size = INIT;
assert ( tempstring != NULL );

int dlen = 1;

int dmax = 1;
factor_t *factorstr = malloc(INIT);
int break2 = 0;
memset(dict,'\0',INIT);
dict[0] = "";
x = input;

char unmatched[2];
unmatched[1] = '\0';
while(strlen(x)){
    match = 0;
    memset(temp,'\0',temp_size);
    if (dlen>INIT){
        temp_size = temp_size + dlen;
        temp = realloc( temp, temp_size );
        assert( temp != NULL );
    }
    printf("DMAX = %d\n",dmax);
    if (dmax==dict_size){
        dict_size *= 2;
        dict = realloc(dict, dict_size*sizeof(*dict));
        assert(dict != NULL);
    }

    for(j=0;j<dlen;j++){
        if (dlen > strlen(x)){
            dlen = strlen(x) - 1;
            printf("\nRunning out of space! DLEN = %d\n",dlen);
        }
        memset(temp,'\0',temp_size);
        strncpy(temp, &x[0], dlen-j);

        for(k=0;k<dmax;k++){
            if (strcmp(temp,dict[k])==0){
                if ((strlen(temp)+1)>(tempstr_size)){
                    tempstr_size += strlen(temp) + 1;
                    tempstring = realloc( tempstring , tempstr_size);
                    assert( tempstring != NULL );
                }
                unmatched[0] = x[dlen-j];
                memset(tempstring, '\0', tempstr_size);
                strcat(tempstring,temp);
                strcat(tempstring,unmatched);
                dict[dmax] = malloc(strlen(tempstring)+100);
                assert ( dict[dmax] != NULL ) ;
                strcpy(dict[dmax], tempstring);
                dmax++;
                match = 1;
                subtractor = dlen-j;
                if (!j){
                    dlen++;
                }
                break2 = 1;
                break;
            }
            }
            if (break2){
                break2=0;
                break;
        }
    }
    if (!match){
        unmatched[0] = x[0];

        factorstr[dmax].c = unmatched[0];
        factorstr[dmax].k = 0;

        dict[dmax] = malloc(INIT);
        assert ( dict[dmax] != NULL );

        memset(dict[dmax],'\0',INIT);
        strcpy(dict[dmax],unmatched);
        printf("dict dmax = %s\n",dict[dmax]);
        dmax++;
        subtractor = 1;
    }
    x = x + subtractor;
}
return 0;

}

【问题讨论】:

  • 你能粘贴一个sscce吗?
  • A short, self-contained compilable example。阅读代码比你的口头描述要容易和可靠得多。如果代码很长,请尝试将行为隔离在更短的代码中并发布。
  • 至于您的问题,您可能应该在调试器中运行以捕获崩溃/中止,并检查分配内存的大小并确保索引在范围内。
  • 您执行x = malloc(INIT),然后在循环之前分配x = input,从而丢失分配内存的句柄。
  • malloc 返回内存句柄。您应该保持该句柄,直到您再次使用free 释放内存。通过覆盖此句柄,您将丢失它并且以后无法释放它。这称为内存泄漏。 (把分配的内存想象成一个数组。你也不能重新分配一个数组。)

标签: c pointers dictionary


【解决方案1】:
memset(dict,'\0',INIT);

这是一个错误,没有任何意义。 dict 是指向指针数组的指针。它不是字符串,也没有大小INIT

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-02-02
    • 1970-01-01
    • 2018-06-26
    • 1970-01-01
    • 2011-07-14
    • 2013-09-24
    • 2013-10-11
    • 2012-10-09
    相关资源
    最近更新 更多