당신은 항목의 시퀀스에서 항목의 바이트 크기를 놓치고 복사되는 오래된 배열 B를 malloc을 가정합니다. 이 : A
에서 개최 된 주소로 B
에서 개최 된 주소
memcpy(A, B, oldLen);
단순히 복사 oldLen
바이트. 항목이 1 바이트 크기가 아니라면 (포인터가 아닙니다) 개수가 너무 적습니다.
memcpy(A, B, oldLen * sizeof (char*));
마지막으로,이 코드
char **newArray(char **B, int oldLen, int newLen)
{
char **A = realloc(B, newLen * sizeof(char*));sizeof(char*));
if(A == NULL)
{
// Note: B is still valid here. What you want to do with it
// including nothing, is up to you. Your current logic just
// terminates the process, so we leave it alone and just exit.
perror("Failed to allocate");
exit(1);
}
return A;
}
을 단순화하기 위해
realloc
을 사용할 수 있습니다 : 당신이 동일한 코드의 이전
malloc
통화에서했던 것처럼, 항목 크기는 바이트 크기 계산에 포함되어야합니다
구현의 메모리 관리자가 시퀀스를 확장해야하는 경우 이전 버퍼에서 새 버퍼로 모든 복사본을 수행하고 이전 버퍼를 해제합니다. 그러나 추가 혜택이 있습니다 : 할당 채우기.
대부분의 동적 메모리 관리자는 고정 할당 페이지 크기를 가지고 있습니다. 예를 들어 할당량이 아무리 작은 경우에도 할당자는 가장 가까운 배수 인 16 바이트로 올림 할 수 있습니다. 물론 요청한 크기를 기억하지만 내부에는 용량이입니다. 새로 확장 된 공간 요청이 realloc
인 경우 기존 용량 내에서 "맞는"경우 실제로 재 할당 할 필요가 없습니다. 대신, 구현은 단순히 현재 할당의 "사용 된"크기를 업데이트하여 용량이 더 많이 사용되었음을 알리고 과 동일한 포인터를 전달할 수 있습니다. 이렇게하면보다 효율적인 메모리 관리가 가능 해지고 작은 단위로 처리하면 잠재적으로 훨씬 더 빠른 크기 조정이 가능합니다.
그냥 고려해야 할 사항입니다.
'oldLen * sizeof (* A)'. 이미 할당량에 대해 올바른 계산을 수행했습니다. 'memcpy '에서도 그렇게하지 않으시겠습니까? 아니면 더 나은 여전히'realloc'. – WhozCraig
@ n.m. 그는 문자 배열을 복사하지 않고 포인터 배열을 복사합니다. –
@WhozCraig 'memcpy (A, B, oldLen * sizeof (* A));'를 의미합니까? 나는 memcpy를 오랫동안 사용하는 방법을 배웠고 void * memcpy (void * dest, const void * src, size_t n)를 발견했다. memcpy를 사용하는 방법입니다 ... 나는 A와 B가 이중 포인터 인 경우 생각하고 있습니다. memcpy를 사용하여 배열 포인터를 다른 포인터에 복사 할 수 있습니까? – HxH