Jorge Cespedes
Jorge Cespedes

Reputation: 597

C function returns a value but caller assigns another value

I have a C function named from_binary_to_decimal, which is called by another function x_caching. The problem is that from_binary_to_decimal returns for example 2.25 (a float) but x_caching (that has a line wrote to store the return value) modifies the previous value returned by the first function.

I put images of the code (in the order under which they are executed):

float** cache_provider(struct INPUT_DATA* d, char** arrszChromosomes)
{
    static float** arrfCache = NULL;
    int i;
    if (d == NULL && arrszChromosomes == NULL) return arrfCache;

    if (arrfCache == NULL)
    {
        arrfCache = (float**)malloc(d->m_iPopulationSize * sizeof(float*));
        for (i = 0; i < d->m_iPopulationSize; ++i)
        arrfCache[i] = (float*)malloc(2 * sizeof(float));
    }

    x_caching(d, arrszChromosomes, &arrfCache);

    return arrfCache;

}

void x_caching(struct INPUT_DATA *d,
               char **arrszChromosomes,
               float **arrfCache)
{  
    int i;
    float fTemp = 0.0f;

    for (i = 0; i < d->m_iPopulationSize; ++i) {
        arrfCache[i][0] = get_cache_key(arrszChromosomes[i]);
        fTemp = from_binary_to_decimal(d, arrszChromosomes[i], 0);
        arrfCache[i][1] = fTemp;
    }
}

float from_binary_to_decimal(struct INPUT_DATA *d,
                             char *szChromosome,
                             int iCacheQuery)
{  
    float fRetVal = 0.0;
    float fFinal = 0.0f;
    float *fCacheVal = NULL;
    int i = 0;

    if (iCacheQuery
        && (fCacheVal = get_x_value_from_cache(szChromosome)) != NULL)
        return *fCacheVal;

    for (i = 0; i < strlen(szChromosome); ++i)
        fRetVal +=
            (szChromosome[i] == '1' ? 1 : 0) *
            powf(2, d->m_iBitsPChromosome - (i + 1));

    fFinal = d->m_arrcDomainInterval[0] + (fRetVal * d->m_fDelta);
    return fFinal;
}

fTemp was supposed to store a number like 2.51 instead it is storing a value like 8133608.

Upvotes: 1

Views: 112

Answers (2)

Valeri Atamaniouk
Valeri Atamaniouk

Reputation: 5163

You never set arrfCache to non-null value. Futhermore, the x_caching should have declaration of the form:

void x_caching (struct INPUT_DATA* d, char** arrszChromosomes, float*** arrfCache)

As you want arrfCache to be output parameter.

x_caching(d, arrszChromosomes, &arrfTempCache);
...
*arrfCache = malloc(....)
....
(*arrfCache)[i][0] = ...

Upvotes: 3

user2088639
user2088639

Reputation:

For starters the number of float arrays you're allocating, and your array indexes used to access them, are different:

arrfCache = (float**)malloc(d->m_iMaxGenerations * sizeof(float*));
for (i = 0; i < d->m_iPopulationSize; ++i)
    arrfCache[i] = (float*)malloc(2 * sizeof(float));

You've allocated d->m_iMaxGenerations float arrays, but you're iterating through d->m_iPopulationSize of them.

Same for the for loop where you have fTemp:

for (i = 0; i < d->m_iPopulationSize; ++i)

You're accessing arrfCache for d->m_iPopulationSize arrays, when you've only allocated d->m_iMaxGenerations. If d->m_iMaxGenerations is smaller, this could lead to memory corruption and weird values such as you've seen.

Upvotes: 3

Related Questions