2013-03-24 1 views
0

최근에 C 포인터에 문제가 발생했습니다. 보시다시피, STDIN에서 데이터를 읽는 루프가 있습니다. 문제는 내가 한 일을 이해하지 못한다는 것입니다.C - 메모리 할당 문제 - 필요 설명

이 struct_CONTAINER 구조체에 메모리를 할당했습니다. 내부에 BUFFER_SIZE 길이의 C- 문자열 배열이 필요했습니다. 올바르게 이해한다면,이 배열은 BUFFER_SIZE (char *) 객체를 포함합니다 -이 배열의 가중치는 8 * BUFFER_SIZE 바이트 (각 char 포인터 당 최대 8 바이트)가된다는 의미입니다. 예를 들어, BUFFER_SIZE가 값 10으로 정의 된 경우이 배열에 대해 80 바이트가 주어지며 아마도 전체 구조가 비슷한 크기를 갖게됩니다.

문제는 그 포인터에 대해 BUFFER_SIZE보다 큰 값으로 반복 할 수 있으며, 저에게 이상한 점은 메모리가 NULL이 아니라는 것입니다. 그 루프에서 나는 이미 할당 된 다른 메모리에 접근하려고 할 수도 있다는 것을 알고 있습니다. 그러나 나는 확실하지 않다. 누군가가 좋을 것이고 내가 옳고 그른 일을하고 있다고 나에게 말하면. 메모리 할당이 너무 많을 수 있습니다. 미리 감사드립니다!

char *item = NULL; 

if(dup2(STDIN_FILENO, fdin) < 0){ 
    perror("dup2()"); 
    exit(errno); 
} 

memset(reading, '\0', BUFFER_SIZE); 

struct struct_CONTAINER{ 
    char *container[BUFFER_SIZE]; 
}; 


while((r_control = read(fdin, reading, BUFFER_SIZE-1)) > 0){ 
    item = &shmemContainer->container[i++]; 
    strcpy(item, reading); 
    memset(reading, '\0', BUFFER_SIZE); 
} 

편집 : 나는 container은 문자열의 배열을 의미 char* 유형 인 "항목"변수

+1

항목 유형이 도움이되지 않습니다. @Grijesh Chauhan의 답을 읽어보십시오. – Aneri

+0

"컨테이너"배열이 가리키는 문자열에 대해 다른 곳에 메모리를 할당합니까? – Digikata

+0

@Digikata 당신이 맞습니다 이것은 OP에 의한 추가 오류 일 수 있습니다. 당신이 내 대답은 –

답변

1

귀하의 구조체 멤버의 유형이 무엇인지를 보여주고 잊어 버렸습니다. item 주소로 char**의 주소를 지정하고 전화를 걸어보십시오 strcpy(item, reading);

다음 문장 중 하나에서 적어도 잘못하고 있습니다.

item = &shmemContainer->container[i++]; 
     ^ is wrong 
strcpy(item, reading); 
     ^or this is wrong 

[답변]precedence of -> operator is higher then & 때문에
(당신이 첫 번째 점을 주석으로는 코드에 오류입니다). 코드를 컴파일 할 때 경고 메시지가 나타납니다.

item = (&shmemContainer)->container[i++];

  • strcpy(item, reading); 잘못 맞다면 그것을 좋아 :

    • 첫 번째 표현식 item = &shmemContainer->container[i++]; 잘못 쓰기 인 경우는 좋아

      strcpy(*item, reading);

    등을 나는 당신의 while 루프에서 이해할 수있는 당신은 문자열 배열로 fdin에서 문자열을 읽어 원하고 당신처럼 수행 할 수 있습니다, reading[r_control] = '\0';이가 처음으로 때문에 memset() 누락 추가

    while((r_control = read(fdin, reading, BUFFER_SIZE-1)) > 0){ 
        reading[r_control] = '\0'; // null ternimate 
        strcpy(shmemContainer->container[i++],reading) ; 
        memset(reading, '\0', BUFFER_SIZE); 
    } 
    

    코드 \0 문자열을 종료하지 않습니다 read() 기억이 본인.

    편집 : 당신이 container[]strcpy()을하고 있기 때문에
    는 각 문자열에 대한 메모리를 할당 있는지 확인 Digikata의 코멘트 @ 고려하십시오.

    나의 제안 : 당신이 누락 된 경우

    i = 0; 
    while((r_control = read(fdin, reading, BUFFER_SIZE-1)) > 0){ 
        reading[r_control] = '\0'; // null ternimate 
        shmemContainer->container[i] = malloc(strlen(reading) + 1); 
        strcpy(shmemContainer->container[i++],reading) ; 
        memset(reading, '\0', BUFFER_SIZE); 
    } 
    

    추가 메모리 할당 : 당신처럼, 당신의 while 루프에서 메모리를 할당 할 수 있습니다

    container[] 문자열의 배열입니다.

  • +0

    죄송합니다. "item"변수 유형을 지정하는 것을 잊어 버렸습니다. 그것의이다 char * item; 이것은 내 배열의 단일 C 문자열입니다. 임 다른 임무를 수행하고 조금 더 단축하고 싶었습니다. 전체 코드가 작동하지만 메모리가 null 인 배열 항목에 액세스 할 수 있다는 점에 놀랐습니다. – Garet

    +0

    @ Kuntaker 이미 내 답변에서 언급했습니다. 만약 당신의'item'이'char *'타입이라면'item = & shmemContainer-> container [i ++];'는'()'를 추가하거나 작성한 while 루프를 변경합니다. –

    +0

    내가 어떻게 이해하는지 설명해 주겠다. 당신이 나를 고쳐 주면 친절 하리라. 연산자 "->"> "&"연산자 때문에 먼저'shmemContainer'의 'container' 인 멤버 에 액세스하고 있습니다. 2. 연산자 "[]"로 메신저 값이 점점 높아져 (여기에 확실하지 않음) 3. 포인터가 필요하기 때문에 & 연산자를 사용하여 4. 마지막으로 im 이 주소를 (char *) 포인터 처럼'item = & shmemContainer-> container [i ++]; ' – Garet

    0

    C는 의도 한 메모리 위치 이후의 색인 생성을 방해하지 않습니다. 예를 들어 : 거기, 거기에 자주 자료입니다 만 정의되지 않은 동작이 발생합니다 (를 읽어도 때로는)을 쓰기로

    char astring[5] = "0123"; // there is a zero at index 4 
    char* ptr = astring;  // ptr[4] == 0 
    
    printf("%c", ptr[5]); // reads a byte beyond the end of the string array 
    

    코드는 논리적으로 발생하는 것을 방지 할 필요가있다. 따라서 코드에서 컨테이너가 아닌 영역은 NULL이 아닌 것으로 읽는 것이 일반적입니다.

    BTW, C 문자열을 가리키는 char * 형식과 할당 된 메모리 영역 (예 : 위의 코드에서 "ptr", "astring"변수)의 차이를 이해하면 명확하지 않습니다. 샘플 코드는 문자열에 메모리를 할당하지 않습니다.