2011-12-24 3 views
0

malloc의 메모리에 사용자 정의 유형에 대한 포인터를 전달하고이 포인터가 포인터를 가리 키도록 설정합니다. malloc()에는 포인터가 붙어 있지만, 함수에서 돌아 왔을 때, 포인터가 움푹 들어가 있습니다. 포인터 매개 변수가 손상되었습니다. 포인터를 반환하거나 포인터의 주소를 전달합니다.

  • 오히려 포인터 자체가 내가이 경우에 가깝다 의심
  • 보다 포인터의 주소를 전달할를 전달하는 대신

    • 반환 포인터 : 나는 수정의 몇 함께했다 FILE 포인터; 함수에 포인터를 건네 주면, 시스템이 그 포인터로 도약 할 수 있기 때문에 포인터가 변경되지 않았다고 계산할 수 없습니다. 그래서 대신 FILE *의 주소를 전달합니다.

      누구든지 설명이 있으십니까? 여기에 (죄송합니다, 그건 조금 긴) 코드의 다음과 같이

      //variable declarations 
      INVENTORY *inv = NULL; 
      
      //process 
      initInventory(inv, bookArySize); 
      processFile(inv); 
      

      initInventory() 기능은 다음과 같습니다 INVENTORY은 위와 같이 사용자 정의 유형이

      typedef struct { 
          BOOK *bookAry; 
          int numBooks; 
      }INVENTORY; 
      

      내가 main()이 있었다 :

      void initInventory(INVENTORY *inv, int size) { 
      
          //process 
          inv = (INVENTORY *) malloc(sizeof(INVENTORY)); 
           //more code here.... 
          return; 
      
      }//initInventory 
      

      그래서 우리는 새로 할당 된 메모리를 가리키는 inv (그리고로 (우리가 생각하는) main()로 돌아다른 포인터가있는 구조체를 가리킴). 포인터 invprocessFile()에 전달할 때만 문제가 발생하고 inventory 구조체의 데이터를 참조하려고하면 액세스 위반이 발생합니다. main()으로 돌아 가면 포인터가 유효하지 않습니다.

      이 그것을 고정 : main()이 있습니다

      //variable declarations 
      INVENTORY *inv = NULL; 
      
      //process 
      inv = initInventory(inv, bookArySize); 
      processFile(inv); 
      

      initInventory()이 변경됩니다 :

      INVENTORY * initInventory(INVENTORY *inv, int size) { 
      
          //process 
          inv = (INVENTORY *) malloc(sizeof(INVENTORY)); 
      
      
          //return a pointer to the INVENTORY header struct 
          return inv; 
      
      }//initInventory 
      

      는 그런 내가 더 나은 수정 생각하는이를 시도했다.

      //variable declarations 
      INVENTORY *inv = NULL; 
          //more code here... 
      
      //process 
      initInventory(&inv, bookArySize); 
      processFile(inv); 
      

      을 다음과 같이 initInventory()은 다음과 같습니다 : main() 지금이

      void initInventory(INVENTORY **inv, int size) { 
      
          //process 
          *inv = (INVENTORY *) malloc(sizeof(INVENTORY)); 
           //more code here.... 
          return; 
      
      }//initInventory 
      
    +2

    C의 인수는 항상 값의 모든 유형의 매개 변수에 의해 전달됩니다. 그래서'inv'를 넘길 때'inv'의 값, 즉'NULL'을 넘깁니다. 그런 다음, 함수 내에서 그 값은 * local *'inv' 변수에 할당됩니다.이 변수는 여러분의 마음 내용에서 변경할 수 있습니다. – pmg

    답변

    0

    당신은 여기에서 무엇 :

    void initInventory(INVENTORY *inv, int size) { 
    
        //process 
        inv = (INVENTORY *) malloc(sizeof(INVENTORY)); 
        //more code here.... 
        return; 
    
    }//initInventory 
    

    은 기본적으로 이것이다 : 당신은 매개 변수로 주소의 사본을 전달합니다 그런 다음 사본을 변경하십시오. 그것은 그 기능 안에서 size에 무엇인가를 할당하는 것과 같은 효과가 있습니다 : 단지 로컬 복사본을 변경합니다.

    "수정 사항"은 두 가지 올바른 해결책입니다. 변경할 변수에 대한 포인터 (이 경우 포인터에 대한 포인터)를 전달하거나 malloc의 포인터를 반환하십시오.

    btw : malloc의 반환 값을 캐스트하지 말아야합니다.당신은 아무 것도 얻지 못하고 잠재적 인 문제를 숨 깁니다. this question도 참조하십시오.

    +0

    나는 항상 malloc에서 리턴을 던지기를 가르쳤지 만, 당신이 지적한 쓰레드는 좋은 지적입니다. 설명과 링크를 보내 주셔서 감사합니다. –

    0

    기본적으로 포인터를 값으로 전달하면 매개 변수로 복사되고 호출 된 포인터는 호출 된 함수로 변경할 수 없습니다. malloc()은 전달 된 매개 변수 인 OK에 할당하지만 복사본으로 변경됩니다 * INV는 NULL을 유지합니다. 명시 적으로 포인터를 반환하거나 참조 (**)에 의해 포인터를 전달하면 malloc()에 의해 반환 된 포인터가 호출자 변수에로드되므로 반환 후에 호출자가 성공적으로 역 참조 할 수 있습니다.

    FILE 포인터와 동일한 문제입니다. 호출 된 함수 내에서 파일을 열고 반환 후 호출자에서 액세스하려는 경우 FILE * 값을 전달할 수 없습니다.

    +0

    위의 대답에서 줄 4는 둥근 괄호 안에 별표 2 개가 있어야합니다. 나는 2 *로 타이핑했는데, 어떤 이유로 그 답은 단 하나만있는 것으로 보입니다. 나는 2 *를 입력 할 수 없습니다. stackoverflow 페이지 스크립트 일부 isue ?? –

    +1

    @Martin : 백 슬래시 별표 (\\ *)를 사용하십시오. 별표는 이탤릭체와 굵게 표시에 사용되며 백 슬래시를 사용하면 "보통"으로 나타납니다 – pmg

    +1

    별표 두 개가 ** 굵은 글씨 **입니다. 백 쿠웨이트 (코드)로 슬래시 또는 줄 바꿈. – kfmfe04

    관련 문제