2012-09-07 1 views
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; 
} 
+2

그래서 두 개의 프로그램이 있는데, 하나는 작동하지 않는 프로그램이고 다른 하나는 작동하지 않는 프로그램이고 우리는 문제가 무엇인지 * ? 또는 나는 무엇인가를 오해 했느냐? – jalf

+0

그리고 작동하는 프로그램은'main()'을 포함하지 않으므로 작동하는 프로그램의 일부입니다 ... MessageBox, TEXT 및 MB_OK가 정의되지 않았거나이 코드에서 선언 되었기 때문에 코드가 제대로 컴파일되지 않습니다 . 메모리 할당을 확인하는 것은 좋지 않을 수도 있습니다. –

+0

큰 사람은 다른 사람이 그것을 통해 분류 할 것을 기대하기에는 너무 큽니다. 질문은 : 나는 포인터와/또는 (m) (c) alloc으로 무언가를하고 있는가? –

답변

0

이 코드는 실행되어 5 개의 '오류'메시지를 생성하며 메모리가 누출되지 않습니다. Mac OS X 10.7.4 (GCC 4.7.1 사용)에서 valgrind (3.7.0)을 실행하면 깨끗한 상태가됩니다.

이 코드 버전에서는 문제가 발생하지 않습니다.

#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; 
} 
+0

잘 알고 있습니다. 고맙습니다. –