0

問題は私がそれを解放できないことです.コンソール出力ポインタはfree関数内で同じです.reallocが呼び出されたときに関数StringList_addからの行でxcodeが検出されました.

typedef struct stringlist_s {
        int max_str;
        char **str;
}stringlist_t;

//functions
stringlist_t *StringList_new()
{
    stringlist_t *lst = (stringlist_t *)malloc(sizeof(stringlist_t));

    return lst;
}

void StringList_add(stringlist_t *str_list,char *str)
{
    if(!str)
        return;
    if(!str_list)
        return;

    str_list->str = (char **)realloc(str_list->str, sizeof(char *)  * (str_list->max_str+1));

    str_list->str[str_list->max_str] = (char *)malloc(strlen(str) + 1);

    memcpy(str_list->str[str_list->max_str], str, strlen(str) + 1);

    str_list->max_str++;
}

void StringList_release(stringlist_t *strList)
{
    if(!strList) {
        printf("Releasing empty pointer\n");
         return;
    }

    for(int i = 0 ; i < strList->max_str; ++i )
    {
        free(strList->str[i]);
        printf("pointer inside is %p\n",strList->str[i]);
    }

    printf("list before is  %p\n",strList);
    free(strList);
    printf("list  now is %p\n",strList);  //value is the same as previous printf

}

これを使用して上記のコードをテストします。

stringList_t *a = StringList_new();
StringList_add(a,"abc");
StringList_add(a,"edf");
StringList_release(a);
4

1 に答える 1

4

問題はStringList_new()、新しいメンバーを割り当てstringList_tますが、メンバーを初期化しないことです。への呼び出し時realloc():

str_list->str = (char **)realloc(str_list->str, sizeof(char *)  * 
    (str_list->max_str+1));

初期化されていないstr_list->strstr_list->max_str、初期化されていません。の参照ページからrealloc()

これは、malloc()、calloc()、または realloc() によって事前に割り当てられ、free() でまだ解放されていない必要があります。それ以外の場合、結果は未定義です。

これは、初期化されたポインターで使用する場合に当てはまります。

への変更:

stringlist_t *StringList_new()
{
    stringlist_t *lst = malloc(sizeof(*lst));
    lst->max_str = 0;
    lst->str     = NULL;

    return lst;
}

malloc()orの戻り値をキャストしないでくださいrealloc()NULLへのポインターを渡すことは問題ありません。その場合realloc()のように動作します。戻り値を一時ポインタ変数に格納して、失敗した場合のメモリ リークを回避するmalloc()場合:realloc()realloc()

char** tmp = realloc(str_list->str, sizeof(*tmp)  * (str_list->max_str+1));
if (tmp)
{
    str_list->str = tmp;
}

C標準に従って、すべてのビット0がnullポインターを表す必要がないため、使用calloc()しなかったことに注意してください。StringList_new()

于 2012-10-16T17:58:13.857 に答える