문제
다음은 배열 내 구조체의 그리고 intarr_get
기능이 당신이 testi에 있었던 방식이었습니다. 유효하지 않은 색인입니다. 이를 처리하는 올바른 방법은 ai->data
의 현재 할당 된 크기를 ai->len
으로 저장하는 것입니다. 현재 할당 된 크기를 유지하면 index
에 대한 ai->len
의 쉬운 테스트를 통해 유효성을 확인할 수 있습니다. 그것은 또한 당신이 심지어 나중에 realloc
ai->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
확실하지'IA-> 데이터 [인덱스] = 0 '외설' 잘못된 색인에 대한 적절한 검사. 인덱스가 범위를 벗어난 경우에도 값이 0이 아니며 인덱스가 배열 범위 내에 있더라도 값이 0 (코드 당) 일 수 있습니다. –
@ 대니얼 그래, 나는 그것에 대해서도 생각했다. ia-> data [index] < ia-> len이 유효한 인덱스를 더 잘 검사하는지 확인 하시겠습니까? –
색인 자체만으로는 데이터를 확인할 필요가 없습니다. 'index < ia-> len' –