2013-05-20 2 views
0

현재 프로그램에서 큰 문제가 있습니다. 루프 내부에서 다른 함수 호출을하면이 함수가 두 함수가되어 영원히 루프가 발생합니다! printf("bah");도 영원히 반복 할 수 있습니다.free()가없는 malloc() 호출의 실제 결과는 무엇입니까? 영원히 반복되는 프로그램과 같은 프로그램을 만들 수 있습니까?

이렇게하면 정상적으로 실행됩니다.

//size = 10 (example) 
while(size > 0) { 
    a(); // decrement by 2 
    b(); // decrement by 2 
} 

그러나

//size = 10 (example) 
while(size > 0) { 
a(); // decrement by 2 
b(); // decrement by 2 
putchar(' '); 
} 

은 영원히 루프를 지정합니다. 다른 하나는 putchar() 호출입니다.

무언가를 취하는 것은 어렵지만, 무엇이 상상을 초월한 것입니까?

무엇 a() and B()`기능이 기본적으로 수행

이 배열에서 두 구조체는, 1printf() 회원들의 일부에 의해 size을 감소 얻을. 이러한 구조는 프로그램 최종 단계에서만 해제되지 않습니다.

나는 (포착 할 수있는) 잡동사니에 대한 아이디어를 얻기 위해이 코드 부분을 게시했습니다. 이 코드 부분의 모든 코드는 정말 큽니다.

편집 :

여기에 최소한의 a()b() implmentation이야 :

void a(void) { 
    foo_t* f = top; 
    while(f->y == STATE_X) { 
    get(&a); get(&b); /* it's equivalent to pop() in a linked list. size is size=size-1 in each get call() */ 
    printf("%d,%d\n",a->x,ab->x); 
    f = f->next; 
} 
top = f; 
} 

void a(void) { 
    foo_t* f = top; 
    while(f->y == STATE_Y) { 
    get(&a); get(&b); /* it's equivalent to pop() in a linked list. size is size=size-1 in each get call() */ 
    printf("%d,%d\n",a->x,ab->x); 
    f = f->next; 
} 
top = f; 
} 

get()이 - 내 상황에서 pop() 내 동일합니다.

top - 마지막부터 struct footype까지 스택에서 처리.

size - 현재 스택에있는 요소의 수입니다.

struct footype도이 링크와 마찬가지로 구현되어 있으며 이전 및 다음 구성원을 가리키는 prevnext이 있습니다.

+0

메모리 누수 ... –

+0

더 많은 코드를 게시해야합니다. – HAL9000

+0

아니요, 메모리가 부족한 경우가 아니라면 ... 코드에 따라 다름) 무한 루프가 발생하지 않습니다. 함수 내에서 뭔가를하고 있습니다 (아마도 "크기"와 같은 실수가없는 한 포인터를 가지고있을 것입니다). 여기에 작은 함수 예제를 작성해보십시오. 아마도 그 점을 잘못 작성했는지 알 수있을 것입니다. 그리고 적절한 답을 줄 충분한 정보를 얻을 것입니다. –

답변

5

메모리가 할당되었지만 해제되지 않은 코드에 대해 말하면 순전히 끝내면 메모리는 프로그램이 끝날 때까지 할당 된 채로 남아 있습니다. 해제하지 않고 더 많은 메모리를 할당하는 경우, 결국에는 ... malloc이 실패하고 null 포인터를 반환 할 수 있습니다. (물론, 널 포인터를 통해 메모리에 접근하려고하면 C 표준을 따른다면 모든 종류의 괴짜가 발생할 수 있습니다. 리눅스에서 가장 일반적인 결과는 세그 폴트입니다.)

그러나, ulimit 설정이 없으면 모든 스왑 공간도 함께 사용하게 될 것이므로 결국에는 느려질 수 있습니다. 물론 프로세스 내에서 모든 메모리를 사용하면 다른 프로세스에서이를 제거 할 수 있습니다. 결국, 두 가지 중 하나가 일어날 가능성이 높습니다 :

  • 다른 프로세스가 메모리를 할당하지 못한 시작할 수 있습니다 ... 그리고 그들은 그 설명되지 않은 경우, 그들은 중단 될 수 있습니다.

  • 리눅스는 가상 메모리를 의도적으로 나눠줍니다 - 기본적으로 RAM과 스왑 공간이없는 메모리 페이지. (이유는 약간 복잡하지만 문맥에 따라 의미가 있습니다.) 프로세스가 실제로 그 메모리를 사용하려 할 때만 커널이 그것을 위해 약간의 RAM을 긁어 모을 것입니다. 여유 공간이없고 교체 할 공간이 없다면 커널은 기존 프로세스를 중단하여 가상 메모리를 회수합니다.

    (이까지 죽일 수있는 프로세스를 결정하는 알고리즘이 있다고된다면 그것은 최악의 범죄자 memorywise의 과정 선호 할 것 -..이 경우, 아마 당신입니다,)

그 정도는 손상 정도입니다. 당신은 일을 상당히 느리게 할 것이고, 다른 프로세스를 망쳐 버릴 것이며, 아마도 그들 중 하나가 죽게 될 것입니다.

적어도 혼자서는 할 수없는 한 가지 일은 원인 루프가 영원히 계속되도록하는 것입니다. 이를 야기하기 위해서는 프로그램이 (1) 실패를 확인해야하고, (2) 작업과 관련된 아무 것도 변경하지 않고 성공할 때까지 실패한 작업을 영원히 다시 시도해야합니다.

다른 문제가 있습니다.

+0

'ulimit'이란 무엇입니까? – Jack

+1

@Jack : (프로세스 셸)과 그 자식에 대한 다양한 리소스 제한을 가져 오거나 설정할 수있는 프로그램, 셸 명령 및/또는 시스템 호출 (컨텍스트에 따라 다름)입니다. 이러한 제한 중 하나는 OS가 사용하지 못하게 할 메모리의 양입니다. – cHao