[완료] malloc, realloc을 사용한 메모리 할당 문제입니다.
글쓴이: yundorri / 작성시간: 월, 2008/06/16 - 2:41오후
아래와 같이 프로그램을 했습니다.
구조체를 만들어서 1000개만큼 새로 메모리를 할당받아
임의의 내용을 집어넣는 프로그램입니다.
그런데 실행을 하면 중간에 세그가 납니다.
왜 나는지 도저히 모르겠습니다.
고수님들 도와주십시요~~~~
#include [stdio.h] #include [string.h] #include [stdlib.h] typedef struct FILE_STRUCT { char filename[128]; long filestamp; } FILE_S; int main( int argc, char** argv ) { int count = 0; FILE_S* mem; for( int i = 0; i < 1000; i++ ) { printf( "TP1: File %03d... ", count ); if( ! count ) { mem = (FILE_S*)malloc( sizeof(FILE_S) ); memset( mem, 0, sizeof(FILE_S) ); printf( "size %d bytes created and bzeroed\n", sizeof(FILE_S) ); } else { mem = (FILE_S*)realloc( mem, sizeof(FILE_S) + sizeof(FILE_S)*count ); memset( mem, 0, sizeof(FILE_S) + sizeof(FILE_S)*count ); printf( "size %d bytes re-allocated and bzeroed\n", sizeof(FILE_S) + sizeof(FILE_S)*count ); } strcpy( (mem + count*sizeof(FILE_S))->filename, "asdfasdf.txt" ); // 나중에 file명이 들어갑니다. (mem + count*sizeof(FILE_S))->filestamp = i+1; // 읽은 파일의 시간스탬프가 들어갑니다. (정렬을 목적으로) count++; } for( int i = 0; i < count; i++ ) // 제대로 저장이 되었나 확인하는 부분입니다. { printf( "File %03d [%s] = %ld\n", i+1, (mem+ i*sizeof(FILE_S))->filename, (mem+ i*sizeof(FILE_S))->filestamp ); } free( mem ); return 0; }
실행결과입니다.
[yundorri@swdev2 filesort]$ ./test TP1: File 000... size 132 bytes created and bzeroed TP1: File 001... size 264 bytes re-allocated and bzeroed TP1: File 002... size 396 bytes re-allocated and bzeroed TP1: File 003... size 528 bytes re-allocated and bzeroed TP1: File 004... size 660 bytes re-allocated and bzeroed TP1: File 005... size 792 bytes re-allocated and bzeroed TP1: File 006... size 924 bytes re-allocated and bzeroed TP1: File 007... size 1056 bytes re-allocated and bzeroed TP1: File 008... size 1188 bytes re-allocated and bzeroed 세그멘테이션 오류 [yundorri@swdev2 filesort]$
Forums:
pointer 계산이 잘못되었습니다.
mem의 type이 FILE_S *이므로 character로 계산하여 sizeof(FILE_S)를 곱해주면 문제가 생깁니다. pointer의 증감 연산은 type의 크기를 계산하므로 sizeof는 불필요합니다.
mem + count*sizeof(FILE_S) -> mem + count
mem + i*sizeof(FILE_S) -> mem + i
조기 나중에 파일명
조기 나중에 파일명 들어갑니다...거기서 부터 아래로
구조체 포인터 호출시에
사이즈는 빼주시면 되겠습니다.
위 코드에서 *sizeof(FILE_S)를 빼주시면 됩니다.
34번째 줄부터군요..^^;
구조체 포인터 역시
일반 포인터와 마찬가지로 덩어리를 통째로 가는것이 아니라 포인터 주소만 가지므로
각각의 크기연산은 필요없습니다.
laziness, impatience, hubris
不恥下問 - 진정으로 대화를 원하면 겸손하게 모르는 것은 모른다고 말하는 용기가 필요하다.
laziness, impatience, hubris
不恥下問 - 진정으로 대화를 원하면 겸손하게 모르는 것은 모른다고 말하는 용기가 필요하다.
네.. 해결되었습니다. 근데요...
감사합니다. 두 분 도움으로 일차문제는 해결되었습니다.
그런데, realloc() 이 새로할당 받은 주소에 기존 주소에서 가지고 있던 메모리 내용을 복사해 준다고
되어있던데,
http://www.winapi.co.kr/clec/cpp1/10-3-4.htm
실제로는 복사를 안 해주더군요.
이게 int*나 char* 같이 간단한 경우에는 복사를 잘 해주는데 struct와 같이 복잡한 경우에는 안되는건지
는 잘 모르겠습니다. 그래서 위 코드에 두 분 말씀대로 sizeof를 빼고 했더니 마지막 file만 남는 현상으로
복사가 안된다고 생각을 해서 현재 사이즈만큼 임시변수로 할당받고 백업을 한 뒤 realloc하고 복사를
해 주었더니 잘 되었습니다.
그런데 이렇게 하면 performance 면에서 많이 불리해 질것 같은데 이럴 수 밖에없는 건지요?
php의 array_sort 기능을 만들어볼라니까 무지하게 힘들군요. T_T
realloc은 내용을 보존해 줍니다.
다만 realloc 이후에 memset으로 내용을 지우시더군요.
memset( mem, 0, sizeof(FILE_S) + sizeof(FILE_S)*count );
이 부분은 의도적인 부분으로 생각했습니다만 아니었나보군요.
의도하신대로의 동작을 하려면
memset( mem + count, 0, sizeof(FILE_S) );
가 되어야 합니다.
제가 잘못 이해했나
제가 잘못 이해했나 보군요!!!
man realloc을 하면 새로 할당되는 부분은 초기화가 되지 않는다 라는 부분이 있어서
memset을 했던건데 그러면 안되는 거였네요.
실~~수!!!
메모리풀을 만들고,
메모리풀을 만들고, 메모리풀 사용량이 모자랄경우에 다시 realloc을 하는 구조를 사용하시는것이 더 좋을듯합니다.
realloc의 비용은 싸지 않습니다. 특히나 그것이 반복문안에 들어있을 경우... ㅡㅡ;;
처음 충분한 공간의 메모리풀을 확보해서 사용하고, 풀이 모자랄경우, 다시 특정한 용량만큼을 realloc하는 구조로 바꾸시면 perfomance 향상에 도움이 될것입니다.
時日也放聲大哭
時日也放聲大哭
처음에 만드는
처음에 만드는 메모리풀 변수명으로 나중에 확장이 가능한가요?
예를 들어,
FILE_S file_list[128];
로 만들었는데 file의 개수가 128개를 초과하여 256개로 늘리고 싶다면...
file_liist를 ...
file_list = realloc( file_list, sizeof( FILE_S ) * 256 );
이렇게 해도 될까요???
실험을 해 보면 알 수 있겠지만.. 아시는 분 계시면 ㅎㅎㅎ
안될것 같은데...
#define POOL_SIZE 128int
대충 개념상으로 이런식이 되겠죠.
자세한 직접 try 해보시는게 젤 좋습니다. :)
時日也放聲大哭
時日也放聲大哭
아.. 네. 잘
아.. 네. 잘 이해했습니다.
감사합니다.
댓글 달기