2017-12-09 9 views
-3

포인터 변수 (반환되지 않음)를 통해 함수 내에서 지역 변수를 전달하려고합니다.함수의 지역 변수를 매개 변수로 다시 전달합니다.

내 할당은 스택 데이터 구조를 사용하며, 사용해야하는 기준 중 하나는 Pop() 함수가 스택의 맨 위에있는 항목을 반환하는 데 사용되는 포인터 매개 변수를 가져야한다는 것입니다. 나는 이것을 전에 사용했다. 내 프로그램이 데이터 구조체와 더 복잡 해짐에 따라 세그멘테이션 오류가 발생하거나 함수 프레임이 팝 된 후 데이터가 저장되지 않습니다.

// Definitions 
typedef char * string; 
typedef enum { SUCCESS, FAIL } result; 
typedef enum { INTEGER, DOUBLE, STRING } item_tag; 


// Result Check 
static result RESULT; 


// Item_Tag 
typedef struct { 
    item_tag tag; 
    union { 
     int i; 
     double d; 
     string s; 
    } value; 
} item; 

// Declarations 
int STACK_SIZE = 0; 
const int MAX_STACK_SIZE = 1024;  // Maximum stack size 
item stack[1024]; 

// Pop 
result Pop(item *ip){ 
    item poppedItem; 
    item * pointerReturn = malloc(sizeof(item)); 

    // Check stack size is not 0 
    if(STACK_SIZE == 0){ 
     return FAIL; 
    } 
     // If stack size is only 1, creates a blank stack 
    else if(STACK_SIZE == 1){ 
     item emptyItem; 
     // Initialize 
     emptyItem.tag = INTEGER; 
     emptyItem.value.i = 0; 

     // Check top item's tag 
     poppedItem = stack[0]; 
     // Store top item data based on tag 
     switch(stack[0].tag){ 
      case STRING: 
       poppedItem.value.s = stack[0].value.s; 
      case DOUBLE: 
       poppedItem.value.d = stack[0].value.d; 
      default: 
       poppedItem.value.i = stack[0].value.i; 
     } 
     poppedItem.tag = stack[0].tag; 
     // Allocate memory for parameter, and have it point to poppedItem 
     ip = malloc(sizeof(poppedItem)); 
     *ip = poppedItem; 
     // Store empty stack to top of stack 
     stack[0] = emptyItem; 

     // Decrease stack size 
     STACK_SIZE--; 

    } 
     // Grab top Item from stack 
    else{ 
     // Check top item's tag 
     poppedItem = stack[0]; 
     // Store top item data based on tag 
     switch(stack[0].tag){ 
      case STRING: 
       poppedItem.value.s = stack[0].value.s; 
      case DOUBLE: 
       poppedItem.value.d = stack[0].value.d; 
      default: 
       poppedItem.value.i = stack[0].value.i; 
     } 
     poppedItem.tag = stack[0].tag; 
     // Allocate memory for parameter, and have it point to poppedItem 
     ip = malloc(sizeof(poppedItem)); 
     *ip = poppedItem; 

     // Reshuffle Items in Stack 
     for(int idx = 0; idx < STACK_SIZE; idx++){ 
      stack[idx] = stack[idx + 1]; 
     } 
     STACK_SIZE--; 
    } 
    return SUCCESS; 
} 

포인터에 관한 나의 지식은 괜찮으며, 메모리 위치/관리. 그러나 어떤 방법 으로든 전문가가 될 수 있다고 주장 할 수는 없습니다. 필자는 데이터를 다시 전달하는 수단으로 함수의 자체 포인터 매개 변수를 사용할 때 배경에서 어떤 일이 발생하는지 정확히 알지 못합니다.

  1. 이 문제를 해결하기위한 올바른 구문은 무엇입니까?
  2. 어떻게 매개 변수를 전달할 수 있습니까?

미리 감사드립니다.

EDIT * 많은 사람들이 혼란 스럽습니다. 나는 약간의 발췌 문장을 게시 할 것이다. 이 과제는 과제이므로 부적절한만큼 온라인으로 게시 할 수는 없습니다. 하지만 함수 자체를 게시하고 사람들이 분석하도록하는 것이 좋습니다. 나는 해결책을 찾기 위해 수십 번 편집했기 때문에 다소 지저분한 일이라고 생각합니다. 혼란을 드려 죄송합니다. 모든 코드가있는 것은 아닙니다. 문제의 기능과 구조의 일부.

item catcher; 
myFunc(&catcher); // Pass a pointer to catcher 

을하고 함수는 포인터를받은 개체를 수정해야합니다 :

+6

는 C 또는 C++인가? 둘 다 함께 태그하지 마십시오. – iBug

+1

당신은 포인터에 대한 지식이 괜찮다고 주장했지만, 나는 catcher.variable이 누군가 현명한 사람에 의해 쓰여졌다 고 생각하지 않는다. 점 대신에'->'를 써야합니까? – iBug

+1

@Ron이 말한 것에 덧붙여, C를 배우면이 [C 책 모양] (/ q/562303/5958455)을 살펴 봐야합니다. – iBug

답변

2

함수는 유효한 개체에 대한 포인터를 받아야

void myFunc(item *itemPointer) 
{ 
    itemPointer->variable = stuff; 
    // or 
    *itemPointer = someItem; 
} 

업데이트 :

당신 '을 overcomplicating 것들을 대단히 - 당신이 터지기 때 아무도 malloc가 없어야하고, 당신은 장소 전체에 메모리를 새고있어.

그것은 더 같은 것을해야한다 (.. 포인터와 메모리 관리에 대한 지식은 "확실히는"그것은 더 많은 지식보다 초보자의 추측처럼 보인다는 거리가 멀다) :

result Pop(item *ip){ 
    if (STACK_SIZE == 0){ 
     return FAIL; 
    } 
    else { 
     *ip = stack[0]; 
     for(int idx = 0; idx < STACK_SIZE; idx++){ 
      stack[idx] = stack[idx + 1]; 
     } 
     STACK_SIZE--; 
    } 
    return SUCCESS; 
} 

하지만 더 나은

result Pop(item *ip){ 
    if (STACK_SIZE == 0){ 
     return FAIL; 
    } 
    else { 
     *ip = stack[STACK_SIZE-1]; 
     STACK_SIZE--; 
    } 
    return SUCCESS; 
} 
+0

을 클릭하면 변경 사항에 액세스 할 수 있습니다. 이전에 시도한 바였습니다. 함수의 프레임 스택이 팝되면 "someItem"의 주소는 저장되지 않습니다. 여기 오른쪽 팝()가 종료 된 후 GDB에서 판독 같습니다 <> (GDB) 디스플레이 topItem 1 topItem = {태그 = 정수 값 = {I = 0, D- = 0, S = 0x0으로}} (gdb) display bottomItem 2 = bottomItem = {tag = (알 수 없음 : 9242040), 값 = {i = 1, d = 4.9406564584124654e-324, s = 0x1 <오류 : 주소 0x1의 메모리에 액세스 할 수 없음>}} < > – Sappharite

+0

원래 게시물을 수정하고 코드의 일부를 추가했습니다. – Sappharite

+0

정말 대단히 죄송합니다. 숙제와 대학 가이드 라인을 매우 조심해야합니다. 내 코드가 지저분 해. 예. 솔직히, 함수의 범위 밖에서 뭔가를 반환하거나 수정하는 수단으로 매개 변수를 사용할 때 혼란 스러웠습니다. 나는 여기 모두에게 사과한다. 나는 SOF를 사용한 적이 없으며, 나는 대부분의 사람들을 쳤다. – Sappharite

0

원래 게시 된 코드에 대한 응답 :

typedef struct{ 
    variables 
}item; 

void myFunc(item *itemPointer){ 
    item newItem; 
    newItem.variable = stuff; 
} 

int main(){ 
    item * catcher; 
    myFunc(catcher); 
    printf("%s\n", catcher.variable); 
} 
01 배열의 끝에서/팝을 밀어

몇 가지 문제가 있습니다.

프로그램이 컴파일되지 않습니다. variable에는 유형이 있어야합니다.

void myFunc(item *itemPointer){ 
    item newItem; 
    newItem.variable = stuff; 
} 

stuff은 정의되지 않는다. item *itemPointer은 사용되지 않습니다.

item * catcher 포인터는 할당 된 메모리를 가리켜 야합니다. 초기화되지 않았습니다.

void myFunc(item *itemPointer, const char *string){ 

    itemPointer->variable = string ; 
} 

솔루션과 같은 : 같은 구조의

포인터를 통해

패스 인수를 수정 회원

void myFunc(item *itemPointer) 
{ 
    itemPointer->variable = stuff; 
    // or 
    *itemPointer = someItem; 
} 

이 가능하지만, stuff 또는 someItem가 아닌 global variable 있다고 가정 최고의 프로그래밍 실습.

->이 아닌 . 연산자를 통해 포인터에서 값을 가져옵니다.

#include <stdio.h> 
#include <stdlib.h> 

typedef struct{ 
    char * variable; 
}item; 

void myFunc(item *itemPointer, const char *string){ 

itemPointer->variable = string ; 
} 

int main(){ 
    item * catcher; 
    char *new_string = "new string"; 

    catcher = malloc(sizeof(item)); 

    myFunc(catcher, new_string); 
    printf("%s\n", catcher->variable); 
    free(catcher); 
    return 0; 
} 

출력 :

new string 
+0

나는 원래 게시물을 편집하고 코드 스 니펫을 게시했습니다. 아마도 그것이 무슨 일이 일어나는지 이해하는 데 도움이 될 것입니다. – Sappharite