2011-10-05 4 views
1

그래서 내 프로그램에서 malloc을 사용하고 프로그램 안의 메서드 내에서 realloc을 사용했습니다. 이 메서드를 여러 번 호출 한 후에 "분할 오류 (코어가 덤프 됨)"가 발생합니다.Segfault with realloc

추가 검사시, 예를 들어 내 포인터가 0x25d7d60 또는 0x223fae0 (또는 7 자리 숫자 (0xHHHHHHH)로 표시되는 주소)에서 0x7f47d370a010 (7 자리 숫자 이상)으로 갈 때 어떤 이유로 인해 segfault가 발생합니다. realloc 호출 내에서 realloc은 NULL을 반환하지 않습니다. malloc을 사용한 다음 memcpy를 사용하여이 문제를 해결했습니다. 그러나 나는 왜 이런 일이 일어 났는지에 대해 혼란스러워하며 stackoverflow 사용자가 왜 이런 일이 일어 났는지에 대해 알 수 있기를 원합니다.

unsigned int* myArray; 
unsigned int num_ints; 

int main() 
{ 

    num_ints = 100; 
    if((myArray =(unsigned int*) malloc(sizeof(unsigned int)*(num_ints)*3))==NULL) 
    { 
    std::cout << "Malloc failed!" << std::endl; 
    return false; 
    } 

    . 
    . 
    . 

    //This called when n key is pressed (code left out) 
    methodName(); 
return true; 
} 

void methodName() 
{ 

if((myArray =(unsigned int*) realloc(myArray,sizeof(unsigned int)*(num_ints*4)*3))==NULL) 
{ 
    std::cout << "Realloc failed!" << std::endl; 
    exit(0); 
} 

} 
+0

코드를 표시하십시오 .. – phoxis

+0

코드하십시오 .... –

+0

C 또는 C++로되어 있습니까 ??? 왜 태그가 C이고'std :: cout'을 사용합니까? – AnT

답변

5

, "프로그램 내 방법 내에서 realloc을"을 호출하여, 당신은 실제로 로컬 변수로를로드하는 좋은 기회가있다 :

덕분에 여기

는 관련 코드 이 포인터는 버려지고 프로그램은 더 오래된 포인터 (이제는 해제되었습니다)를 계속 사용합니다.

코드가 확실해야하지만, 제 경험상 할당 오류의 주요 원인 중 하나입니다.


표시 한 내용을 기반으로하고있는 일에 아무런 문제가 없습니다. 이 코드와 실질적으로 동일합니다.

#include <iostream> 
#include <cstdlib> 
int sz = 1000; 
int *buffer = 0; 
static int methodName (void) { 
    if (sz == 100000) 
     sz = 100; 
    sz = sz * 10; 
    if ((buffer = (int*)realloc (buffer, sz)) == 0) { 
     std::cout << "Realloc error" << std::endl; 
     return 1; 
    } 
    return 0; 
} 
int main(void) { 
    int i; 
    if ((buffer = (int*)malloc (sz)) == 0) { 
     std::cout << "Alloc error" << std::endl; 
     return 1; 
    } 
    for (i = 0; i < 10000000; i++) 
     if (methodName() != 0) 
      return 1; 
    std::cout << "All okay" << std::endl; 
    return 0; 
} 

천만 개의 재 할당을 수행하면 완벽하게 작동합니다.

그래서 문제는 여러분이 우리에게 보여준 것, 아마도 코드의 다른 곳에서 컴파일러 버그 (주류 컴파일러를 사용하는 경우에는 거의 없을 것 같음) 또는 메모리 손상 일 가능성이 있습니다. 다음 배열의 주소 (지역) 기능 범위의 myarr을 변경 realloc 경우

+0

게시물에 코드를 추가했습니다. 실제 코드는 아니지만 매우 유사합니다. 내가 사용한 코드는 포인터를 전역 변수로 가졌습니다. – Matt

+0

@Matt, 내가 게시 한 코드에 아무런 이상이 없음을 알 수 있습니다. 실제 코드 또는 적어도 문제를 나타내는 코드 (가능한 한 가장 작은 변형)를 게시해야합니다. – paxdiablo

+0

동의합니다. 그리고 이것은 myArray와 num_ints 변수 이름과 methodName의 이름을 변경 한 것 외에는 실제 코드입니다. – Matt

3

그것이 main

+---------+ 
| val1 | = malloc (whatever); <--------------------------+ 
+---------+              | 
|myarr |              | 
+---------+              | 
|addr_main|              | 
+----+----+              | 
    |               | 
    |               | 
    |            (NO EFFECT on here) 
(value of the myaddr 'val1')         | 
(in main passed by value)          | 
(to function)             | 
    |               | 
    +-------+             | 
      |             | 
      v             | 
methodname (myarr, someint)          | 
      |             | 
      |             | 
      V             | 
     +---------+            | 
     | val1 | = realloc (myarr, whatever)  ---------+ 
     +---------+  
     |myarr | if 'realloc' returns a new address 
     +---------+ it will only overwrite 'val1' with some 'val2' 
     |addr_func| in this LOCAL copy with address 'addr_func' 
     +---------+ 
      | 
      | 
      V 
    (destroyed after function return) 
+0

그래, 그건 내 실제 코드가 아니 었어 ... 난 그냥 그렇게했다. 내 실제 코드는 내 학교 컴퓨터에있는 코드가 아닙니다. 내 실제 코드에서 myArray는 전역 변수 – Matt

+0

이었지만 작동해야합니다. – phoxis

+0

나는 그것이해야한다고 알고 있고 n 번 키를 눌러 10 번과 같은 더 많은 메모리를 얻고 현재 메모리의 주소가 0xHHHHHHH이고 0xHHHHHHHHHHHH 일 때까지 작동하지 않습니다. 내 Mac에서 잘 작동하고 Linux 머신에 ssh가있을 때, 실제로 리눅스 머신에있을 때는 작동하지 않습니다. – Matt

0

당신은하지 않았다 변화에 myarr 변수를 변경하지 않고, 새로운 값을 가져옵니다 myArr은 주요 범위에서 realloc이 새 주소를 반환 할 수 있으며 이전 주소는 유효하지 않습니다.

+0

그래, 그건 내 실제 코드가 아니 었어 ... 난 그저 비행 중에 그랬어. 내 실제 코드는 내 학교 컴퓨터에있는 코드가 아닙니다. 내 실제 코드에서 myArray는 글로벌 변수였습니다. – Matt

0

문제는 사용자의 methodName 함수가 새 포인터를 myArray의 로컬 복사본에 할당하고 있다는 것입니다.

void methodName(unsigned int **myArray, unsigned int num_ints) 
{ 
    if((*myArray = (unsigned int *)realloc((*myArray), sizeof(unsigned int)*(num_ints*4)*3)) == NULL) 
    { 
     std::cout << "Realloc failed!" << std::endl; 
     exit(0); 
    } 
} 

을 다음 인 myArr의 주소를 전달하여 호출 :

methodName(&myArr, n_ints); 

그런 식의 methodName로 가져

빠른 수정과 같이 포인터에 myArray의 포인터를 만드는 것입니다 main() myArr의 메모리 주소를 써서 쓸 수 있습니다.이 mainmyArr을 덮어 단지 문제 그리고

unsigned int *methodName(unsigned int *myArray, unsigned int num_ints) 
{ 
    return (unsigned int *)realloc(myArray, sizeof(unsigned int) * (num_ints * 4) *3); 
} 

:

당신이 비록 볼 수 있듯이, 기능을 갖는 것은 내가 대신 return 제안 새 주소를 보내고 출력 값이 약간의 털이 얻을 수있는 매개 변수

myArr = methodName(myArr, n_ints); 
+0

제 실제 코드가 아니 었으니까요. 내 실제 코드는 내 학교 컴퓨터에있는 코드가 아닙니다. 내 실제 코드에서 myArray는 글로벌 변수였습니다 – Matt

+0

@Matt 여기에 질문을 게시 할 때 세부 정보는 매우 중요합니다. 질문에서 코드를 수정하면이 대답이 업데이트됩니다. –

+0

질문에서 코드를 업데이트했습니다. 죄송합니다. – Matt