2017-11-03 22 views
0

다음은 코드입니다.C에서이 포인터의 메모리를 확보하는 방법은 무엇입니까?

주요 기능 :

char** doublePtr = malloc((argc - 1) * sizeof(*doublePtr)); 
int i; 
for(i = 0; i < argc - 1; i++) 
{ 
    doublePtr[i] = (char*) malloc((1 + strlen(argv[i + 1])) * sizeof(*doublePtr[i])); // allocate enough space for each string 
    strcpy(doublePtr[i], "hello"); 
} 

// I need to do this so that my function validate can check for this condition 
doublePtr[i] = NULL; 
// Now time to print our output 
validate(doublePtr); 
for(int j = 0; j <= i - 1; j++) { 
    free(doublePtr[j]); 
} 
free(doublePtr); 

내 인쇄 기능 : 나중에 다음

void validate(char* data[]) 
{ 
    int i = 0; 
    while(data[i] != NULL) 
    { 
     printf("%s ", data[i++]); 
    } 
    printf("\n"); 
} 
나는 모든 malloc이 메모리를 통해 첫 번째 반복하는 모든 메모리를 해제하려고 끝을 향해

및 (for 'j'루프 외부) 최종 변수 doublePtr을 해제합니다. 하지만 계속 free:invalid pointer 오류가 발생합니다.

strlen (argv [i + 1])이 "hello"보다 크다고 가정합니다.

답변

1

배열을 NULL 종료하기 때문에 포인터 argc-1이 아닌 argc을 할당해야합니다.

이 작동 :

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

void validate(char* data[]) 
{ 
    int i = 0; 
    while(data[i] != NULL) 
    { 
     printf("%s ", data[i++]); 
    } 
    printf("\n"); 
} 

int main(int argc, char**argv) 
{ 
    char** doublePtr = malloc(argc * sizeof(*doublePtr)); 
    //^ (argc - 1) => argc (to make room for the NULL terminator) 

    if(!doublePtr) return 1; // <= You should also check against allocation failures. 

    int i; 
    for(i = 0; i < argc - 1; i++) 
    { 

     doublePtr[i] = (char*) malloc((1 + strlen(argv[i + 1])) * sizeof(*doublePtr[i])); // allocate enough space for each string 
     if(!doublePtr[i]) return 1; 
     strcpy(doublePtr[i], argv[i+1]); 
    } 

    // I need to do this so that my function validate can check for this condition 
    doublePtr[i] = NULL; 
    // Now time to print our output 
    validate(doublePtr); 

    for(int j = 0; j <= i - 1; j++) { 
     free(doublePtr[j]); 
    } 
    free(doublePtr); 

} 

설명 :

효율적인 메모리 할당이 먼저 제어 블록 바로 옆에 이전, doublePtr[0]에 다음 할당을 배치 할 것이기 때문에 (할당자를 대개 할당량 앞에 약간의 메타 데이터가 있습니다)는 doublePtr[argc-1-1] 바로 뒤에 올 것입니다. 즉, doublePtr[argc-1]에 쓰기 (NULL 쓰기)하면 doublePtr[0]의 제어 블록이 손상되고, free(doublePtr[0])에 패닉이 발생합니다.

또는 "범위를 벗어난 메모리 액세스로 인해 프로그램이 정의되지 않은 상태가 될 수 있습니다."

+0

그래서'doublePtr [i] = NULL;을하기 전에 malloc을 사용해야합니다. 그러나 그때조차도 효과가 없습니다. – ThisSiteSucks

+0

@ThisSiteSucks 아니요, 첫 번째 malloc은'(argc-1) * sizeof (* doublePtr)'이 아니라'argc * sizeof (* doublePtr)'을 요청해야합니다. 그렇지 않으면'doublePtr [i] = NULL' 쓰기가 bounds를 사용하면 프로그램을 정의 할 수 없습니다. – PSkocik

+1

그래, 그건 완전히 의미가 있습니다. 감사. – ThisSiteSucks