2014-11-30 2 views
0

intarr_set()에 대해 인덱스가 유효한 경우 ia [인덱스]의 값을 val로 설정하고 INTARR_OK를 반환하는 두 가지 함수가 있습니다. 이는 상태 코드이며 다른 함수 intarr_get()은 인덱스가 유효한 경우 * i를 ia [index]로 설정합니다. 그러나 임의의 배열을 사용하여 함수를 테스트 할 때 [11 49 36 3 69 21 72 73 94 69 2 22 2 96 64 93], intarr_get() 함수가 반환되지 않는다는 메시지가 나타났습니다. INTARR_OK 유효한 인덱스가 있어도. 아무도 내가 잘못 갔다는 것을 아는 사람이 있습니까?유효한 인덱스를 가진 배열이 올바른 상태 코드를 반환하지 않습니다.

typedef struct { 
    int* data; 
    unsigned int len; 
} intarr_t; 

여기 intarr_set 내 함수의 :

intarr_result_t intarr_set(intarr_t* ia, 
       unsigned int index, 
       int val) 

{ 
    if (ia == NULL) 
    { 
     return INTARR_BADARRAY; 
    } 
    else 
    { 
     if (ia->data[index] != 0) 
     { 
      ia->data[index] = val; 
      return INTARR_OK; 
     } 
     else 
     { 
      return INTARR_BADINDEX; 
     } 
    } 
    return 0; 
} 

을 그리고 여기 intarr_get 내 기능입니다 : 당신의 intarr_set

intarr_result_t intarr_get(const intarr_t* ia, 
       unsigned int index, 
       int* i) 
{ 
    if (ia == NULL) 
    { 
     return INTARR_BADARRAY; 
    } 
    else 
    { 
     if (ia->data[index] != 0) 
     { 
      if (i != NULL) 
      { 
       *i = ia->data[index]; 
      } 
      return INTARR_OK; 
     } 
     else 
     { 
      return INTARR_BADINDEX; 
     } 
    } 
    return 0; 
} 
+2

확실하지'IA-> 데이터 [인덱스] = 0 '외설' 잘못된 색인에 대한 적절한 검사. 인덱스가 범위를 벗어난 경우에도 값이 0이 아니며 인덱스가 배열 범위 내에 있더라도 값이 0 (코드 당) 일 수 있습니다. –

+0

@ 대니얼 그래, 나는 그것에 대해서도 생각했다. ia-> data [index] < ia-> len이 유효한 인덱스를 더 잘 검사하는지 확인 하시겠습니까? –

+2

색인 자체만으로는 데이터를 확인할 필요가 없습니다. 'index < ia-> len' –

답변

1

문제

다음은 배열 내 구조체의 그리고 intarr_get 기능이 당신이 testi에 있었던 방식이었습니다. 유효하지 않은 색인입니다. 이를 처리하는 올바른 방법은 ai->data의 현재 할당 된 크기를 ai->len으로 저장하는 것입니다. 현재 할당 된 크기를 유지하면 index에 대한 ai->len의 쉬운 테스트를 통해 유효성을 확인할 수 있습니다. 그것은 또한 당신이 심지어 나중에 reallocai->data 크기를 유지하는 현재의 방법을 제공합니다. 변경 한 내용과 같다 :

intarr_result_t intarr_set(intarr_t* ia, 
       unsigned int index, 
       int val) 
{ 
    ... 
     // if (ia->data[index] != 0) 
     if (index < ia->len) 
} 

intarr_result_t intarr_get(const intarr_t* ia, 
       unsigned int index, 
       int* i) 
{ 
    ... 
     // if (ia->data[index] != 0) 
     if (index < ia->len) 
} 

변경을 한 후, 짧은 테스트 및 INTARR_BADINDEX 제대로 행동 여부를 테스트 할 수는 index로 제공 배열 번호를 사용하여 설치했다. 결과와 함께 전체 테스트 코드는 아래와 같습니다. 추가 문의 사항이 있으면 댓글을 삭제합니다 :

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

#define INTARR_OK 1 
#define INTARR_BADINDEX -1 
#define INTARR_BADARRAY -2 

typedef int intarr_result_t; 

typedef struct { 
int* data; 
unsigned int len; 
} intarr_t; 

intarr_result_t intarr_set(intarr_t* ia, 
       unsigned int index, 
       int val) 
{ 
    if (ia == NULL) 
    { 
     return INTARR_BADARRAY; 
    } 
    else 
    { 
     // if (ia->data[index] != 0) 
     if (index < ia->len) 
     { 
      ia->data[index] = val; 
      return INTARR_OK; 
     } 
     else 
     { 
      return INTARR_BADINDEX; 
     } 
    } 
    return 0; 
} 

intarr_result_t intarr_get(const intarr_t* ia, 
       unsigned int index, 
       int* i) 
{ 
    if (ia == NULL) 
    { 
     return INTARR_BADARRAY; 
    } 
    else 
    { 
     // if (ia->data[index] != 0) 
     if (index < ia->len) 
     { 
      if (i != NULL) 
      { 
       *i = ia->data[index]; 
      } 
      return INTARR_OK; 
     } 
     else 
     { 
      return INTARR_BADINDEX; 
     } 
    } 
    return 0; 
} 

int main (void) 
{ 
    int rtmp[] = { 11, 49, 36, 3, 69, 21, 72, 73, 94, 69, 2, 22, 2, 96, 64, 93 }; 
    unsigned int rsz = sizeof (rtmp)/sizeof (*rtmp); /* set size of index array  */ 
    unsigned int i = 0; 
    int x = 0; 
    int result = 0; 

    intarr_t myarr = { NULL, 0 };     /* initialize struct to NULL, 0  */ 

    myarr.data = calloc (rsz, sizeof (myarr.data)); /* allocate intarr_t, set to zero */ 
    myarr.len = rsz;        /* save for later realloc & testing */ 

    /* test intarr_set and intarr_get */ 
    printf ("\nSetting and retrieving array values, valid index (0 < index < %d)\n\n", rsz); 
    for (i = 0; i < rsz; i++) 
    { 
     result = intarr_set (&myarr, rtmp [i], i + 1); 
     printf (" set myarr.data[%2u] = %d (return: %s)\n", rtmp[i], i+1, 
       (result > 0) ? "INTARR_OK" : "INTARR_BADINDEX"); 
     intarr_get (&myarr, rtmp [i], &x); 
     printf (" got myarr.data[%2u] = %d (return: %s)\n", rtmp[i], x, 
       (result > 0) ? "INTARR_OK" : "INTARR_BADINDEX"); 
    } 

    printf ("\nResulting myarr.data array\n\n"); 
    for (i = 0; i < myarr.len; i++) 
     if (myarr.data[i]) 
      printf (" myarr.data[%2u] = %d\n", i, myarr.data[i]); 
     else 
      printf (" myarr.data[%2u] = 0\n", i); 
    printf ("\n"); 

    if (myarr.data)         /* free allocated data */ 
     free (myarr.data); 

    return 0; 
} 

출력 :!이 문제에 직접 관련이 있지만, 경우

Setting and retrieving array values, valid index (0 < index < 16) 

    set myarr.data[11] = 1 (return: INTARR_OK) 
    got myarr.data[11] = 1 (return: INTARR_OK) 
    set myarr.data[49] = 2 (return: INTARR_BADINDEX) 
    got myarr.data[49] = 1 (return: INTARR_BADINDEX) 
    set myarr.data[36] = 3 (return: INTARR_BADINDEX) 
    got myarr.data[36] = 1 (return: INTARR_BADINDEX) 
    set myarr.data[ 3] = 4 (return: INTARR_OK) 
    got myarr.data[ 3] = 4 (return: INTARR_OK) 
    set myarr.data[69] = 5 (return: INTARR_BADINDEX) 
    got myarr.data[69] = 4 (return: INTARR_BADINDEX) 
    set myarr.data[21] = 6 (return: INTARR_BADINDEX) 
    got myarr.data[21] = 4 (return: INTARR_BADINDEX) 
    set myarr.data[72] = 7 (return: INTARR_BADINDEX) 
    got myarr.data[72] = 4 (return: INTARR_BADINDEX) 
    set myarr.data[73] = 8 (return: INTARR_BADINDEX) 
    got myarr.data[73] = 4 (return: INTARR_BADINDEX) 
    set myarr.data[94] = 9 (return: INTARR_BADINDEX) 
    got myarr.data[94] = 4 (return: INTARR_BADINDEX) 
    set myarr.data[69] = 10 (return: INTARR_BADINDEX) 
    got myarr.data[69] = 4 (return: INTARR_BADINDEX) 
    set myarr.data[ 2] = 11 (return: INTARR_OK) 
    got myarr.data[ 2] = 11 (return: INTARR_OK) 
    set myarr.data[22] = 12 (return: INTARR_BADINDEX) 
    got myarr.data[22] = 11 (return: INTARR_BADINDEX) 
    set myarr.data[ 2] = 13 (return: INTARR_OK) 
    got myarr.data[ 2] = 13 (return: INTARR_OK) 
    set myarr.data[96] = 14 (return: INTARR_BADINDEX) 
    got myarr.data[96] = 13 (return: INTARR_BADINDEX) 
    set myarr.data[64] = 15 (return: INTARR_BADINDEX) 
    got myarr.data[64] = 13 (return: INTARR_BADINDEX) 
    set myarr.data[93] = 16 (return: INTARR_BADINDEX) 
    got myarr.data[93] = 13 (return: INTARR_BADINDEX) 

Resulting myarr.data array 

    myarr.data[ 0] = 0 
    myarr.data[ 1] = 0 
    myarr.data[ 2] = 13 
    myarr.data[ 3] = 4 
    myarr.data[ 4] = 0 
    myarr.data[ 5] = 0 
    myarr.data[ 6] = 0 
    myarr.data[ 7] = 0 
    myarr.data[ 8] = 0 
    myarr.data[ 9] = 0 
    myarr.data[10] = 0 
    myarr.data[11] = 1 
    myarr.data[12] = 0 
    myarr.data[13] = 0 
    myarr.data[14] = 0 
    myarr.data[15] = 0 
관련 문제