2012-10-01 4 views
24

내가 C. 동적 1D 배열을 만드는 방법을 배우고 아래 코드는이 작업을 수행하려고 :C의 동적 배열 - malloc/realloc에 ​​대한 제 이해가 정확합니까?

  1. 이 의 malloc를 사용하여, 두 배를 보유하고 길이 (10)의 동적 배열을 만듭니다.
  2. 배열의 각 항목을 j = 0,1, ..., 9에 대해 j/100으로 설정하십시오. 그런 다음 을 인쇄하십시오.
  3. realloc을 사용하여 추가로 빈 항목을 어레이 끝에 추가하십시오.
  4. 새 항목을 j/100으로 설정하고 각 항목을 다시 인쇄하십시오.

테스트

double* data = (double*)malloc(10*sizeof(double)); 

for (j=0;j<10;j++) 
{ 
     data[j]= ((double)j)/100; 
     printf("%g, ",data[j]); 
} 

printf("\n"); 

data = (double*)realloc(data,11*sizeof(double)); 

for (j=0;j<11;j++) 
{ 
    if (j == 10){ data[j]= ((double)j)/100; } 
    printf("%g, ",data[j]); 
} 

free((void*) data); 

질문

1) 나는이 권리를 코딩하고 있습니까?

2) 자습서 malloc을 사용하고 (double*)을 앞에 붙이지 마십시오. 예 : 이 비주얼 스튜디오 2010 나를 위해 컴파일되지 않습니다

int *pointer; 

pointer = malloc(2*sizeof(int)); 

는 윈도우 7 오류 "void 형식의 값을 int 형의 실체에 할당 할 수 없습니다"입니다.

왜 내가이 튜토리얼에서 작동합니까? 필자는 그들이 사용한 컴파일러가 내 예제에서 자동으로 (int*)을 채우기 때문에 그것이 맞는지 추측 할 수 있습니까?

+0

"void 형식의 값을 int 형식의 엔터티에 할당 할 수 없습니다"는 * C * 컴파일러에서 생성해야하는 오류가 아닙니다. 문제는 * C++ 컴파일러 *를 사용하고 있다는 것입니다. 소스 파일의 이름이 ' .c'인지 확인하십시오. –

답변

31

끝났습니다.C는 캐스팅없이 int *void * 타입의 값으로 변환 할 수 있기 때문에 C에서

는 (적어도 표준의 1989 버전 이후), mallocrealloc 전에 주조는 불필요하다. 이것은 이 아니라입니다. C++에서는 true이므로,이 코드를 C++가 아닌 C로 컴파일하는 것처럼 들립니다. 코드를 C로 컴파일하는 방법을 결정하기 위해 VS2010의 설명서를 확인하십시오.

표현 *data의 유형 double이기 때문에 sizeof *datasizeof (double)에 해당,

double *data = malloc(10 * sizeof *data); 

:

는 다음은 malloc 전화를 작성하기위한 나의 선호하는 스타일이다. 따라서 유형이 data 인 경우 malloc 전화를 조정할 필요가 없습니다.

realloc 호출의 경우 결과를 임시 포인터 값에 할당하는 것이 안전합니다. 이 버퍼를 확장 할 수 없습니다 경우 realloc는 NULL을 반환합니다, 그래서

double *tmp; 
... 
tmp = realloc(data, 11 * sizeof *data); 
if (!tmp) 
{ 
    // could not resize data; handle as appropriate 
} 
else 
{ 
    data = tmp; 
    // process extended buffer 
} 

가 C에 대한 마이크로 소프트의 지원은 언어의 1989 년 버전으로 끝나는주의 쓰고 안전합니다; 그 이후로 몇 가지 새로운 기능과 비추천 된 오래된 기능을 도입 한 언어 표준이 두 번 개정되었습니다. 따라서 일부 C 컴파일러는 혼합 된 선언 및 코드, 가변 길이 배열 등과 같은 C99 기능을 지원하지만 VS2010은 그렇지 않습니다.

+0

감사합니다. 매우 도움이되었습니다. – Legendre

+0

업데이트 : VS2015는 C99 + 부분 C11 및 WinXP 대상 옵션을 지원합니다. 그래서 Microsoft는 2015 년에 ISO C 지원을 계속했습니다. –

4

C에서 반환 값은 malloc()이 아닙니다.

또한 형식을 malloc() 인수로 인코딩하는 것은 좋지 않습니다.

double* data = malloc(10 * sizeof *data); 
+1

이 컴파일됩니다. 그러나 Visual Studio 2010에서는 "void 형식의 값을 사용하여 double 형식의 엔터티를 초기화 할 수 없습니다"라고 경고합니다. 경고를 그냥 무시해도 괜찮습니까? – Legendre

10

1) 나는이 권리를 코딩 건가요이 더 나은 방법이 있나요?

주로. 그러나 realloc에 실패하면 data = (double*)realloc(data,11*sizeof(double));은 할당 된 메모리에 대한 참조를 잃어 버리기 때문에 임시 포인터를 사용하여 realloc의 반환 값을 보유하고 NULL인지 확인해야합니다. 또한 반환 값 malloc도 확인해야합니다.

2) 자습서 앞에서 (double *)을 넣지 않고 malloc을 사용했습니다.

는 C에서, malloc 그래서 캐스트가 필요하지 않습니다 (오류를 숨길 수 있습니다 주조 때문에 널리 낙담), 암시 적으로 다른 포인터 형식으로 변환 할 수있는 void*을 반환합니다. Visual Studio에서는 코드가 C++로 컴파일되고 캐스트가 필요한 것 같습니다.

+0

+1 도움에 감사드립니다. – Legendre