问题
I have two functions here, which for intarr_set(), if an index is valid, I would set the value at ia[index] to val and return INTARR_OK which is a status code, and the other function intarr_get() would set *i to ia[index] if the index is valid as well. But when I was testing my function with a random array I generated, which was [ 11 49 36 3 69 21 72 73 94 69 2 22 2 96 64 93 ], I got a message saying that my intarr_get() function didn't return INTARR_OK even though I got a valid index. Does anybody know where I went wrong?
Here's my struct for the array:
typedef struct {
int* data;
unsigned int len;
} intarr_t;
Here's my function for 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;
}
And here's my function for intarr_get:
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;
}
回答1:
The problem with your intarr_set and intarr_get functions were in the way you were testing for an invalid index. The proper way to handle this is to store the current allocated size for ai->data as ai->len. Keeping the current allocated size allows for easy testing of index against ai->len to determine validity. It also provides a current way to keep the size in the even you realloc ai->data at some later time. The changes made were:
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 )
}
After making the changes, a short test was setup using the array numbers you provided as index to test whether INTARR_OK and INTARR_BADINDEX behaved properly. The full test-code along with the results are below. Drop a comment if you have further questions:
#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;
}
output:
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
来源:https://stackoverflow.com/questions/27209269/array-with-a-valid-index-is-not-returning-the-right-status-code-in-c