Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pointer and allocation outside function or static variable and allocation inside?

Tags:

c

pointers

static

Don't freak out about the length of my post, it's pretty simple, I just don't know how to put it any shorter:

I have two ways of doing something pretty much similar to merging two arrays via a function. Here I call the function combine_data(). The arrays are called data1 and data2. Suppose my arrays are like:

int num1 = 4;
int num2 = 6;

double data1[num1] = /* some values */
double data2[mum2] = /* some values */

Solution 1

I can either use a solution I find more elegant but I'm unsure if it's good practice and will behave properly. The solution relies on a static variable intended to make the array persistent. Somehow that feels like it could blow up in my face some way.

// SOLUTION 1
double* combine_data(
    const int num1, const double* const data1,
    const int num2, const double* const data2
) {
    int i;
    int num = num1 + num2;
    double *combi;   // static because the data stored the should persist
    combi = (double*)malloc( num*sizeof(*combi) );
    /* some code */
    for(i=0; i<num1; ++i)   combi[i] = data[i];
    for(i=num1; i<num; ++i) combi[i] = data[i];

    return combi;
}

double *combi = combine_data(num1, data1, num2, data2);
/* some code */
free(combi);    // problem with free of a static variable in combine_data() ???

Solution 2

Or I could use the approach I'm more used to, that uses pointers for the same functionality:

// SOLUTION 2
void combine_data(
    const int num1, const double* const data1,
    const int num2, const double* const data2
    double* combi
) {
    /* some code */
    for(i=0; i<num1; ++i)   combi[i] = data[i];
    for(i=num1; i<num; ++i) combi[i] = data[i];
}

int num = num1 + num2;
double *combi = (double*)malloc( num*sizeof(combi) );
combine_data(num1, data1, num2, data2, combi);
/* some code */
free(combi);

Solution 2 has the problem that nothing prevents the user from this: combine_data(num1, data1, num2, data2, data1), which would screw up data1. Solution 2 hides the allocation, and is easier to use, which I find more elegant, but I don't know how it will behave especially when freeing the memory. Which solution is the best and why?

Also btw. is there a difference between the two?:

const int* const name
const int const *name

Edit: One really is a syntax error i've seen in faulty code and wondered. Also discarded the static.

like image 540
con-f-use Avatar asked Aug 16 '11 13:08

con-f-use


1 Answers

Why would you need to make combi static in solution 1? The pointer does not have to persist, only what is pointed to by it. The pointer is then returned by value, so no memory leak occurs.

Which solution you choose depends solely on your assumption as to the style of the whole program. You have to decide whether the function should allocate and return a pointer to allocated memory, or accept a pointer to already allocated memory.

Both solutions are correct, and in my opinion equally good. In solution 2 you may also check for equality between input and output pointers and return an error code. You can even check for memory overlapping, not only pointer equality. But then again, it all depends on what responsibilities you assign to different parts of your program.

like image 185
Michał Trybus Avatar answered Oct 18 '22 19:10

Michał Trybus