0

I already asked a question regarding a program. I got an answer but I have a new issue. The program I wrote is not working and I don't know why.

The function is working fine (I guess) but I want to be sure by printing the values of each element of the array and see if they are correct (I will need this for other purposes).

I tried with a simple for instruction for a printf, but the array seems to be empty. The problem may be related to the memory address of the value I want to print.

Please have a look, any advice will be welcome!

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

int * rand_gen(int N, float fl_value); // Function declaration

int main()  // Main function
{

int N;  // Declaration: Number of trials
printf("Number of trials: ");
scanf("%d", &N);    // Asks for Number of trials

float alpha = 0.3;
float beta  = 0.4;
float gamma = 0.5;
float delta = 0.6;

int i;  // Index
int seed = time(NULL); // Random number generator seed (based on current time)
srand(seed);

// Populate arrays
float *bin_array_alpha[] = { rand_gen( N, alpha ) };
float *bin_array_beta[]  = { rand_gen( N, beta )  };
float *bin_array_gamma[] = { rand_gen( N, gamma ) };
float *bin_array_delta[] = { rand_gen( N, delta ) };



// Here I would like to print the elements of the arrays, something like:

for ( i=0 ; i<N ; i++)
{
    printf("\nbin_array_alpha[%d] = %f",i,bin_array_alpha[i]);
    printf("\nbin_array_beta[%d]  = %f",i,bin_array_beta[i]);
    printf("\nbin_array_gamma[%d] = %f",i,bin_array_gamma[i]);
    printf("\nbin_array_delta[%d] = %f",i,bin_array_delta[i]);
    printf("\n");
}


// Free the memory
static const size_t m = sizeof(bin_array_alpha)/sizeof(bin_array_alpha[0]);

for ( size_t i = 0 ; i < m ; ++i )
{
    free(bin_array_alpha[i]);
    free(bin_array_beta[i]);
    free(bin_array_gamma[i]);
    free(bin_array_delta[i]);

    bin_array_alpha[i] = NULL;
    bin_array_beta[i]  = NULL;
    bin_array_gamma[i] = NULL;
    bin_array_delta[i] = NULL;
}

printf("\n");

return(0);
}


// Function: generate an array populated by: array[j] = rand()*fl_value
int * rand_gen(int N, float fl_value)
{
    int *array;
    array = (int *)malloc(sizeof(float)*N);
    if(array == NULL)
    {
        printf("\nRun out of memory!\n");
        exit(1);
    }

    int j;
    float x;
    for( j = 0 ; j < N ; j++ )
    {
        x = rand(); // Generates a random number
        x = x/RAND_MAX; // 0 < x < 1
        x = x * fl_value;
        array[j] = x; // array[j] = x * fl_value
    }

    return array;
}

The result is always the same (for example N=3):

bin_array_alpha[0] = 0.000000
bin_array_beta[0]  = 0.000000
bin_array_gamma[0] = 0.000000
bin_array_delta[0] = 0.000000

bin_array_alpha[1] = 0.000000
bin_array_beta[1]  = 0.000000
bin_array_gamma[1] = 0.000000
bin_array_delta[1] = 0.000000

bin_array_alpha[2] = 0.000000
bin_array_beta[2]  = 0.000000
bin_array_gamma[2] = 0.000000
bin_array_delta[2] = 0.000000

Thank you so much again!

4
  • Why is array type in rand_gen is int * ? Commented Nov 9, 2015 at 19:47
  • 1
    You have array of pointer-to-float, but you're printing as if you have an array of float. And you're initializing the array with one element from a function that returns a pointer-to-int. Commented Nov 9, 2015 at 19:48
  • @user3386109 so how should I print the pointer to float? And how do I change the initialisation pointer to float rather than pointer to int? Thank you by the way ;) Commented Nov 9, 2015 at 20:01
  • Remove the [] after each of the 4 declarations. The function returns a pointer, although, its int* pointer is incompatible with a float* pointer.. Commented Nov 9, 2015 at 20:07

1 Answer 1

2

your problem is in the allocation of the arrays of float that you not simply confused with int but the technique of allocation is wrong:

float **rand_gen(int N, float fl_value)
{
    float **array;
    array = (float **)malloc(sizeof(float *) * N + 1);
    if (array == NULL)
    {
        printf("\nRun out of memory!\n");
        exit(1);
    }
    int i;
    for (i = 0; i < N; i++)
    {
        array[i] = (int *)malloc(sizeof(float));
        array[i][0] = 0;
    }
    array[N] = NULL;

    int j;
    float x;
    for (j = 0; j < N; j++)
    {
        x = rand(); // Generates a random number
        x = x / RAND_MAX; // 0 < x < 1
        x = x * fl_value;
        *(array[j]) = x; // array[j] = x * fl_value
    }

    return array;
}

An array of float is a pointer to a memory area where each element is a pointer to a float.

This means you have to correct the declaration:

float **rand_gen(int N, float fl_value); // Function declaration

and the usage in the main:

float **bin_array_alpha = rand_gen(N, alpha);
float **bin_array_beta = rand_gen(N, beta);
float **bin_array_gamma = rand_gen(N, gamma);
float **bin_array_delta = rand_gen(N, delta);

The same happens for the printf:

printf("\nbin_array_alpha[%d] = %f", i, *bin_array_alpha[i]);

Instead to free the memory you need to add the free not only of each float but also of the memory base:

free(bin_array_alpha
Sign up to request clarification or add additional context in comments.

4 Comments

Worked! Thank you so much! I used to program in C but never had this kind of things to do (arrays from functions etc.).
Why the float ** you could have taken a float * and why typecast the malloc return as int ** ?? It should be float ** or just omit it.
Why I used the double pointer? To make clear the meaning of memory allocation with pointers of float/char/int/... You are right, indeed the function can be reduced to float *rand_gen(int N, float fl_value) but my intention is to make visible the needs to allocate before the pointer to the array and after the memory required for each element. I could make an example with a design to clarify the memory allocation in c. I apologize for that. I hope now it's clear my intention. Your comments are of a great value for me. Thanks so much
That's great, but as the question is on generating random numbers, the pointer stuffs in addition is not on the context and adds additional complexity which is unrelated.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.