2012-01-07 3 views
0

내 프로그램의 다른 위치에 여러 구조체 배열을 할당해야하므로 함수 (VS 2010) 안에 작업을 넣을 수 있습니다. 컴파일러는 사용 된 초기화되지 않은 변수에 대한 경고를줍니다. 그렇다면 그것을 어떻게 전달할 것인가, 그리고 그것을 함수에서 어떻게 선언 할 것인가? "&"및 "*"의 다양한 변형을 시도했지만 아무런 소용이 없습니다.함수 내에서 메모리 할당을위한 포인터 전달?

(내 코드는 오심의 어떤 형태 발생하는 경우 내가 영어 전공 해요 ... 미리 죄송합니다.)

struct s_stream { 
int blah; 
}; 

void xxyz(void) 
{ 
    struct s_stream **StreamBuild; 
    char *memBlock_1; 

    xalloc(StreamBuild, memBlock_1, 20); 
} 



void xalloc(struct s_stream **StreamStruct, char *memBlock, int structCount) 
{ 
    int i = sizeof(struct s_stream *); 
    if ((StreamStruct=(struct s_stream **) malloc(structCount * i)) == NULL) 
     fatal("failed struct pointer alloc"); 

    int blockSize = structCount * sizeof(struct s_stream); 
    if ((memBlock = (char *) malloc(blockSize)) == NULL) 
     fatal("failed struct memBlock alloc"); 

    // initialize all structure elements to 0 (including booleans) 
    memset(memBlock, 0, blockSize); 

    for (int i = 0; i < structCount; ++i) 
     StreamStruct[i]=(struct s_stream *) &memBlock[i*sizeof(struct s_stream) ]; 
} 
+0

정확하게하려고하는 것은 - 동적으로'struct s_stream' 객체의 배열을 할당하는 것입니까? –

+0

컴파일러의 정확한 경고를 알려주십시오. 특히 컴파일러는 어떤 코드 행을 싫어합니까? –

답변

0

당신은 xalloc 포인터 memBlock_1사본을 통과, 그래서 malloc에 의해 반환 된 주소 복사에 기록되고 결코 호출하는 함수에 도달하지 않습니다. 당신은 아마도 주소가 memBlock_1xxyz에 사용할 수있게하려면 때문에, 당신은 통과해야 포인터 - 투 - 포인터로부터 문자에의 두 번째 인수로,

void xalloc(..., char **memBlock, ...) 

xalloc(..., &memBlock_1, ...);로 부른다. xalloc의 본문에 memBlock의 모든 항목을 *memblock으로 바꿉니다. (*memblock = malloc(blockSize)) == NULL (캐스트 할 필요 없음).

유사하게는, xallocStreamStruct 매개 변수는 결코 xxyzStreamBuild 포인터 - 투 - 포인터 - 투 - 구조체 s_stream 변경되지 않습니다. 의도를 올바르게 해석하면 해당 매개 변수에 포인터 레이어를 추가해야합니다 (예 : void xalloc(struct s_stream ***StreamStruct, ..., ...)) StreamBuild의 주소를 xalloc(&StreamBuild, ..., ...) 호출에 전달하고 함수 본문의 포인터를 참조 해제합니다. (*StreamStruct = malloc(structCount * i)) == NULL.

+0

나는 너의 충고를 따랐다. 2 남은 문제 : 컴파일러는 허용하지 않습니다 : (* StreamStruct = malloc (structCount * i)) ... (struct s_stream **)로 캐스팅해야합니다. 다른 문제는 내가 루프를 통해 포인터를 메모리 블록에 할당하는 마지막 두 줄입니다 : for (int i = 0; i PaeneInsula

+0

'malloc'의 결과를 캐스팅해야한다면 프로그램을 C로 컴파일하는 것이 아니라 C로 컴파일한다는 것을 의미한다. 아마도 큰 문제는 아니 겠지만, 두 프로그램은 (malloc을 반환하는 등을 수행 한 후) 간단한 프로그램을 컴파일하고 둘 다로 작동한다는 점에서 공통점이 있습니다. 루프에서 'for (...) (* StreamStruct) [i] = & memBlock [...];'- 뭔가를 간과하지 않는 한. 흠, '처리되지 않은 예외'. 네, C++. C++로 컴파일한다면 (마이크로 소프트의 컴파일러에서 나쁜 생각은 아니지만 C99을 지원하지 않지만 C++ 컴파일러로도 괜찮습니다), C++을 작성하고 'new'등을 사용하는 것을 고려해보십시오. –

+0

이 맞습니까? for (...) (* StreamStruct) [i] = & memBlock [...]; 또는 for (...) (* StreamStruct) [i] = (* memBlock) [...]; ? 후자는 작동하는 것처럼 보이고 이전에 말한 내용과 일치합니다 ... – PaeneInsula

3

나는 당신의 질문을 이해 정확히 모르겠지만, 그것은 것 같다 struct s_stream 오브젝트를 동적으로 할당 한 배열을 작성하여 호출자에게 리턴하는 함수가 필요합니다. 그런 경우에는, 그것은 꽤 쉽게 :

void easiest(void) 
{ 
    struct s_stream *array = malloc(20 * sizeof(struct s_stream)); 
} 

당신은 포인터 자체의 기능에 떨어져 malloc()를 이동하고 반환 할 수 :

void caller(void) 
{ 
    struct s_stream *array = create_array(20); 
} 

struct s_stream *create_array(int count) 
{ 
    return malloc(count * sizeof(struct s_stream)); 
} 

을 또는 당신은 매개 변수로 배열을 전달 주장하는 경우 :

void caller(void) 
{ 
    struct s_stream *array; 
    create_array(&array, 20); 
} 

void create_array(struct s_stream **array, int count) 
{ 
    *array = malloc(count * sizeof(struct s_stream)); 
} 
+0

첫 번째'create_array()'는'void *'를 리턴해야합니까? 아니면'struct stream * '을 타입 - 안전하도록하는 것이 더 좋다. – alk

+0

예 - 오타. 컴퓨터로 돌아 가면 문제를 해결할 것입니다. –

+0

약간의 시간이 걸리면서 답을 쓰고있을 때의 고정 복사/붙여 넣기 오류. 미안합니다! –

0

일반 배열을 사용하지 않는 이유가 있습니까? 예를 들어;

struct s_stream* streamArray = malloc(sizeof(s_stream*structCount)); 

그럼 방금 여분 포인터를 역 참조없이 [0] streamArray [structCount-1] streamArray에 액세스 할 수 s_stream의 배열을 갖는다.

+0

그게 내가 원래하고 있었던 방법이야. 하지만 배열에 대해 qsort를 사용하려고합니다. (240 만 개 구성원) 무거운 재귀 때문에 스택 오버플로가 발생했습니다. 그래서 대신 포인터를 사용하고 정렬하려고합니다 .... – PaeneInsula

관련 문제