1

このコードを使用する長いバージョンのプログラムと短いバージョンがあります。これは短いバージョンで、奇妙なことに、このコードは短いバージョンのプログラムでは問題なく動作しますが、大きなバージョンではアクセス違反が発生するため、何かがおかしいと感じます。次のコードで何かひどく間違っている (データの破損やアクセス違反エラーにつながる可能性がある) ことに気付いた人はいますか? それともこれでいいの?

char strlist[5][11] = {
    { "file01.txt" },
    { "file02.txt" },
    { "file03.txt" },
    { "file04.txt" },
    { "file05.txt" }
};

typedef struct DYNAMEM_DATA {
    char *string;
    int   strlen;
} DYNAMEM_DATA;

typedef struct DYNAMEM_STRUCT {
    struct DYNAMEM_DATA **data;
    int           num_elements;
} DYNAMEM_STRUCT;

DYNAMEM_STRUCT *create_dynamem_struct(int num_elements, char *strlist)
{
    DYNAMEM_STRUCT *ds = (DYNAMEM_STRUCT *)calloc(1, sizeof(DYNAMEM_STRUCT));
    wchar_t wstring[128];
    char len[3];
    int i;

    ds->data = (DYNAMEM_DATA **)calloc(num_elements, sizeof(DYNAMEM_DATA *));
    ds->num_elements = num_elements;

    for(i = 0; i < num_elements; i++) {
        ds->data[i] = (DYNAMEM_DATA *)calloc(1, sizeof(DYNAMEM_DATA));
        ds->data[i]->string = (char *)calloc(1, strlen(&strlist[i*11])+5);
        ds->data[i]->strlen = strlen(&strlist[i*11]);
        sprintf(ds->data[i]->string, "%s, %d", &strlist[i*11], ds->data[i]->strlen);
        mbstowcs(wstring, ds->data[i]->string, 128);
        MessageBox(NULL, wstring, TEXT("Error"), MB_OK);
    }

    return ds;
}
4

1 に答える 1

0

このコードが実行され、5 つの「エラー」メッセージが生成されますが (これは予想されることです)、メモリ リークは発生しません。( 3.7.0 valgrind) を Mac OS X 10.7.4 (GCC 4.7.1 を使用) で実行すると、問題なく動作します。

どうやら、このバージョンのコードには問題はありません。

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <wchar.h>

char strlist[5][11] = {
    { "file01.txt" },
    { "file02.txt" },
    { "file03.txt" },
    { "file04.txt" },
    { "file05.txt" }
};

typedef struct DYNAMEM_DATA {
    char *string;
    int   strlen;
} DYNAMEM_DATA;

typedef struct DYNAMEM_STRUCT {
    struct DYNAMEM_DATA **data;
    int           num_elements;
} DYNAMEM_STRUCT;

enum { MB_OK = 0 };
static void destroy_dynamem_data(DYNAMEM_DATA *dd)
{
    free(dd->string);
    free(dd);
}
static void destroy_dynamem_struct(DYNAMEM_STRUCT *ds)
{
    for (int i = 0; i < ds->num_elements; i++)
        destroy_dynamem_data(ds->data[i]);
    free(ds->data);
    free(ds);
}
static void MessageBox(const void *null, const wchar_t *wcs, const char *ncs, int status)
{
    if (null == 0 || status == MB_OK)
        fprintf(stderr, "%s\n", ncs);
    else
        fwprintf(stderr, L"%s\n", wcs);
}
static const char *TEXT(const char *arg) { return arg; }

extern DYNAMEM_STRUCT *create_dynamem_struct(int num_elements, char *strlist);

DYNAMEM_STRUCT *create_dynamem_struct(int num_elements, char *strlist)
{
    DYNAMEM_STRUCT *ds = (DYNAMEM_STRUCT *)calloc(1, sizeof(DYNAMEM_STRUCT));
    wchar_t wstring[128];
    //char len[3];
    int i;

    ds->data = (DYNAMEM_DATA **)calloc(num_elements, sizeof(DYNAMEM_DATA *));
    ds->num_elements = num_elements;

    for(i = 0; i < num_elements; i++) {
        ds->data[i] = (DYNAMEM_DATA *)calloc(1, sizeof(DYNAMEM_DATA));
        ds->data[i]->string = (char *)calloc(1, strlen(&strlist[i*11])+5);
        ds->data[i]->strlen = strlen(&strlist[i*11]);
        sprintf(ds->data[i]->string, "%s, %d", &strlist[i*11], ds->data[i]->strlen);
        mbstowcs(wstring, ds->data[i]->string, 128);
        MessageBox(NULL, wstring, TEXT("Error"), MB_OK);
    }

    return ds;
}

int main(void)
{
    DYNAMEM_STRUCT *ds = create_dynamem_struct(5, strlist[0]); 
    destroy_dynamem_struct(ds);
    return 0;
}
于 2012-09-07T23:49:08.270 に答える