2014-05-15 3 views
-2

그게 내가 얻을 수있는 매우 anoing 문제. 내 문제는, gcc 내 int 포인터에 충분한 공간을 할당하지 않는 것 같습니다.C int 포인터 할당 크기

offset = seekToFirstParam(fnString,n); 
i = 0; 
while(i<c) { 
    tmp[i] = readNextParam(fnString,n,offset,&s); 

    if (isFunctionString(tmp[i])) { 
     fns[i] = 1; 
    } else { 
     fns[i] = 0; 
    } 

    i++; 
} 

그래서 이것은 "플래그"배열이지만, 때

fns = (int*)calloc(c,sizeof(int)); 

그래서, 다음 이후에 내가 루프 1과 0 간단한이을 채우기 : 여기

코드입니다 나는이 디버깅, 그리고 내가 얻을 요소를 인쇄 :

156212102, 0, 0, 0, 1, 1

또는 솜을. 이렇게. 나는 이것을 얻지 못한다. 왜냐하면 calloc 메서드에서 1000을 이렇게 쓰면 다음과 같다.

fns = (int*)calloc(1000,sizeof(int)); 

잘 작동하면.

char **readFnParams(char *fnString, int n, int *count, int **func) { 
    char **tmp; 
    int *fns = NULL; 
    int c,i = 0,offset,s; 

    c = getParamsCount(fnString,n); 
    if (!c) { 
     return NULL; 
    } 

    tmp = (char**)calloc(c,sizeof(char)); 
    fns = (int*)calloc(c,sizeof(int*)); 

    offset = seekToFirstParam(fnString,n); 
    while(i<c) { 
     tmp[i] = readNextParam(fnString,n,offset,&s); 

     if (isFunctionString(tmp[i])) { 
      tmp[i] = readNextFunctionParam(fnString,n,offset,&s); 
      offset = seekToNextParam(fnString,n,offset + s - 1); 
      fns[i] = 1; 
     } else { 
      fns[i] = 0; 
      offset = seekToNextParam(fnString,n,offset); 
     } 

     i++; 
    } 
    *func = fns; 
    *count = c; 

    return tmp; 
} 

: 좋아,이 .c 파일이 구멍은 :

좋아,이 정공 함수이다. 예, 이전 q. 숙제 때문에이 연결을 끝내십시오. = SZORZAT (MDETERM (A1 : D4), 나기 (A1 : D4,0), 10,20,30)이 같은

#ifndef exccel_builder_source 
#define exccel_builder_source 

#include "exccel_builder.h" 
#include "exccel_utils.h" 
#include "exccel_function.h" 

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

table* _processing; 

//A végére fűzi az új elemeket 
void addProcess(cell_process **LIST, cell_process *new) { 
    if (*LIST == NULL) { 
     new->next = NULL; 
     *LIST = new; 
     return; 
    } 

    new->next = *LIST; 
    *LIST = new; 
} 

void build(table* table) { 
    int col = table->matrix->col; 
    int row = table->matrix->row; 
    int i,j; 

    table_cell *cellTemp; 
    _processing = table; 

    for (i = 1; i<=row; i++) { 
     for (j = 1; j<=col; j++) { 
      cellTemp = getCell(table,i,j); 
      if (cellTemp != NULL) { 
       buildCell(cellTemp); 
      } 
     } 
    } 
} 

void buildCell(table_cell *cell) { 
    //Begins with '=' 
    if (isFunction(cell)) { 
     buildCellWithFunction(cell); 
    } 
} 

void printProcesses(cell_process *LIST, int tab) { 
    cell_process *tmp = NULL; 
    int i = 0; 
    tmp = LIST; 
    while(tmp != NULL) { 
     i = 0; 
     while(i++<tab) printf(" "); 
     printf("%s, %d, paramPos: %i\n",tmp->func->name,tmp->func->paramsCount,tmp->paramPos); 
     if (tmp->childs != NULL) { 
      i = 0; 
      while(i++<tab + 3) printf(" "); 
      printf("Childs\n"); 
      printProcesses(tmp->childs, tab + 3); 
     } 
     tmp = tmp->next; 
    } 
} 

void buildCellWithFunction(table_cell *cell) { 
    cell_process *HEAD = NULL; 
    buildCellProcessList(cell,&HEAD); 
    cell->cp = HEAD; 

    printf("%d,%d - cella:\n",cell->row,cell->col); 
    printProcesses(HEAD,0); 
} 

void buildCellProcessList(table_cell *cell, cell_process **HEAD) { 
    char *fnString; 
    int size; 

    fnString = getCellStringValue(cell, &size); 
    readFn(fnString,size,1,cell,HEAD,-1); 
} 

int readFn(char *fnString, int n, int offset, table_cell *cell, cell_process **LIST, int paramPos) { 
    char *fnName, *fnParam; 
    int fnNameLength; 
    int *fnSig; 
    int fnSigN; 
    int fnSigI; 
    int sig; 
    exccel_var *vtmp; 
    exccel_function *ftmp; 
    cell_process *ptmp; 
    char **parameters; 
    int *fnIndexes; 
    int paramsCount; 
    int paramI; 
    int i; 

    fnName = readFnName(fnString,n,offset,&fnNameLength); 
    ftmp = getExccelFunction(fnName); 
    if (ftmp == NULL) { 
     return 0; 
    } 

    ptmp = (cell_process*)malloc(sizeof(cell_process)); 
    ptmp->cell = cell; 
    ptmp->func = ftmp; 
    ptmp->paramPos = paramPos; 
    ptmp->t = _processing; 
    ptmp->childs = NULL; 

    addProcess(LIST,ptmp); 

    parameters = readFnParams(fnString,n,&paramsCount,&fnIndexes); 



    allocParams(ptmp->func,paramsCount); 

    paramI  = 0; 

    fnSig = ftmp->signature; 
    fnSigN = fnSig[0]; 
    fnSigI = 1; 

    while(fnSigI <= fnSigN) { 
     sig = fnSig[fnSigI]; 
     if (sig == FN_SIG_RANGE) { 

      fnParam = parameters[paramI]; 
      vtmp = createExccelRangeVarFromString(fnParam); 
      //addParamToFunction(ftmp,vtmp); 
      addParamToFunctionAtPosition(ftmp,vtmp,paramI); 
      paramI++; 

     } else if (sig == FN_SIG_LITERAL) { 

      fnParam = parameters[paramI]; 
      if (fnIndexes[paramI] == 1) { 
       readFn(fnParam,strlen(fnParam),0,cell,&((*LIST)->childs),paramI); 
      } else { 
       vtmp = createExccelVarFromString(fnParam); 
       //addParamToFunction(ftmp,vtmp); 
       addParamToFunctionAtPosition(ftmp,vtmp,paramI); 
      } 
      paramI++; 

     } else if (sig == FN_SIG_LIST) { 

      while(paramI<paramsCount) { 
       fnParam = parameters[paramI]; 
       if (fnIndexes[paramI] == 1) { 
        readFn(fnParam,strlen(fnParam),0,cell,&((*LIST)->childs),paramI); 
       } else { 
        vtmp = createExccelVarFromString(fnParam); 
        //addParamToFunction(ftmp,vtmp); 
        addParamToFunctionAtPosition(ftmp,vtmp,paramI); 
       } 
       paramI++; 
      } 

     } else { 
      printf("Invalid signature %d\n",sig); 
      exit(1); 
     } 

     fnSigI++; 
    } 

    return 1; 
} 

char *readFnName(char *fnString, int n, int offset, int *size) { 
    char *fnName; 
    int nameBuffer, i, j; 

    i = offset; 
    j = 0; 

    nameBuffer = 8; 
    fnName = (char *)calloc(nameBuffer,sizeof(char));  
    while(*(fnString + i) != '(' && i<n) { 
     *(fnName + j++) = *(fnString + i++); 
     if (j>=nameBuffer) { 
      nameBuffer += 8; 
      fnName = (char *)realloc(fnName, nameBuffer); 
     } 
    } 

    *(fnName + j++) = '\0'; 
    *size = j; 

    return fnName; 
} 

char **readFnParams(char *fnString, int n, int *count, int **func) { 
    char **tmp; 
    int *fns = NULL; 
    int c,i = 0,offset,s; 

    c = getParamsCount(fnString,n); 
    if (!c) { 
     return NULL; 
    } 

    tmp = (char**)calloc(c,sizeof(char)); 
    fns = (int*)calloc(c,sizeof(*fns)); 

    offset = seekToFirstParam(fnString,n); 
    while(i<c) { 
     tmp[i] = readNextParam(fnString,n,offset,&s); 

     if (isFunctionString(tmp[i])) { 
      tmp[i] = readNextFunctionParam(fnString,n,offset,&s); 
      offset = seekToNextParam(fnString,n,offset + s - 1); 
      fns[i] = 1; 
     } else { 
      fns[i] = 0; 
      offset = seekToNextParam(fnString,n,offset); 
     } 

     i++; 
    } 
    *func = fns; 
    *count = c; 

    return tmp; 
} 

int getParamsCount(char *fnString, int n) { 
    int i = 0, c = 0, jump = 0; 
    while(i<n) { 

     if (fnString[i] == '(') { 
      jump++; 
     } else if (fnString[i] == ',') { 
      if (jump == 1) c++; 
     } else if (fnString[i] == ')') { 
      jump--; 
     } 

     i++; 
    } 

    if (c > 0) { 
     return c + 1; 
    } else { 
     return 1; 
    } 
} 

int seekToFirstParam(char *fnString, int n) { 
    int i = 0; 
    while(fnString[i++] != '(' && i<n); 

    return i; 
} 

int seekToNextParam(char *fnString, int n, int offset) { 
    int i = offset; 

    while(fnString[i++] != ',' && i<n); 

    return i; 
} 

char *readNextParam(char *fnString, int n, int offset, int *size) { 
    char *params, c; 
    int paramBuffer, i, j; 

    i = offset; 
    j = 0; 
    paramBuffer = 8; 
    params = (char*)calloc(paramBuffer,sizeof(char)); 

    while((c = fnString[i++]) != ',' && c != ')' && c != '(' && i<n) { 
     params[j++] = c; 
     if (j >= paramBuffer) { 
      paramBuffer += 8; 
      params = (char*)realloc(params,paramBuffer); 
     } 
    } 

    params[j] = '\0'; 
    *size = j; 

    return params; 
} 

//Megfelelő számú nyitó (- hez kell hogy legyen ugyanannyi) 
char *readNextFunctionParam(char *fnString, int n, int offset, int *size) { 
    char *fn, c; 
    int fnBf, i, j, fnStarted = 0, fnClosed = 0; 

    i = offset; 
    j = 0; 
    fnBf = 8; 

    fn = (char*)calloc(fnBf, sizeof(char)); 
    while((fnStarted != fnClosed || fnStarted == 0) && i<n) { 
     c = *(fnString + i++); 

     if (c == '(') 
      fnStarted++; 
     else if (c == ')') 
      fnClosed++; 

     *(fn + j++) = c; 
     if (j >= fnBf) { 
      fnBf += 8; 
      fn = (char*)realloc(fn, sizeof(char) * fnBf); 
     } 

    } 
    //*(fn + j++) = ')'; 
    *(fn + j++) = '\0'; 
    *size = j; 

    return fn; 
} 

#endif 

그리고 입력은 때로 믿을처럼

+6

문제를 재현하는 최소한의 편집 가능한 예제가 유용 할 것입니다. –

+1

당신의'readNextParam (fnString, n, offset, &s);')이'fns'의 할당을 처리하고 있다고 추측 할 위험이 있습니다. 그 중 하나는'tmp [i]'할당입니다. 문제를 재현하는 데 필요한 코드. 당신이 속한 코드를 모두 가지고 있다고 가정하고, 우리가 * * * * * * * *하지 않았기 때문에 위장을 그만두십시오 .. 코드와 함께 재생산해야하는 샘플 데이터 – WhozCraig

+0

여기서 볼 수있는 첫 번째 calloc 호출은 정확합니다. @WhozCraig와 협조하여 힙 오버 플로우 (크기가 작은 tmp 또는 s로 인해 발생)가 실제 문제 일 수 있습니다. –

답변

2

그것은 나에게 보인다 t 제대로 할당, 당신은 :

은 첫 번째 줄, TMP, 크기 char (1 바이트의 C 요소)의 c 요소를 할당한다
tmp = (char**)calloc(c,sizeof(char)); 

, 당신이 크기 char *c 요소 (크기 4의 C 요소를 원한다고 생각 또는 요소에 따라 8 바이트 32 또는 64 비트 플랫폼). 일상 readNextParam()이 배열에 저장 char *을 반환, 당신은에 tmp의은 calloc의를 sizeof을 변경해야하기 때문에 :이 때문에

tmp = calloc(c,sizeof(char*)); 

, 나는 당신이 블리드 tmp 배열로 쓸 때 메모리 덮어 믿습니다 다른 배열에 넣으십시오. "1000"요소를 모두 작성하면 덮어 쓰기가되어 첫 번째로 calloc만큼 덮어 쓰면서 덮어 쓰기가 여전히 같은 메모리에 남아있게됩니다.

+1

또한 다음과 같아야합니다. fns = (int *) calloc (c, sizeof (int)); – Jiminion

+2

그것까지는 * 어느 누구도 캐스트를해서는 안됩니다. 이것은 결국 C입니다. 그리고 @ 짐, 후자는 괜찮습니다. 'sizeof (* fns)'는 런타임이 아닌 컴파일 타임에서 정확한 크기로 줄어 듭니다. 그 줄은 괜찮아. – WhozCraig

+0

컴파일러가 (무해한) 캐스트도 처리하지 않습니까? 적어도 캐스트는 난독 화 (및 잘못)되지 않으므로 컴파일러가 처리 할 수있는 경우에도 sizeof 부정확성을 '확인'으로 유지하는 이유는 확실하지 않습니다. – Jiminion