How to use a dynamically allocated vector returned from a function in C?

1

I have a dynamic-sized vector that was created in a function and need to return it to the main function.

The function that returns is as follows:

int* uniao(int *v1, int n1, int *v2, int n2){
    int *v3;
    int i, j = 0;

    //Aloca dinamicamente v3
    v3 = (int*) malloc((n1 + n2) * sizeof(int*));

    //Preenche o vetor com o v1
    for(i = 0; i < n1; i++){
        v3[i] = v1[i];
    }

    //Preenche o vetor com v2
    for(i = n1; i < (n1 + n2); i++){
        v3[i] = v2[j];
        j++;
    }

    return v3;
}

How could I use it in the main function?

I was trying this:

pAux = uniao(&v1, n1, &v2, n2); //Ponteiro Auxiliar recebe &v3

for(i = 0; i < (n1 + n2); i++){
    printf("\n%i", *pAux[i]);
}

But the application ends up closing before displaying the vector. : v

    
asked by anonymous 01.11.2017 / 16:53

2 answers

0

Your program is "closing" before displaying the result because it is causing a segmentation . This error occurs when a program tries to access (to read or write) an address in memory that is reserved for another program.

By using * (asterisk), also known as operador de dereferência in the line:

printf("\n%i", *pAux[i]);

You are trying to access the memory address contained in pAux[i] , which in your case, is the integer value contained in one of the elements of your dynamic buffer pointed to by pAux , which is certainly not a memory address.

There is no need to use operador de dereferência in this case, and the correct one would be:

printf("\n%i", pAux[i]);

Or, if you really like using operador de dereferência , combined with a aritmética de ponteiros " simple, you can do something like:

printf("\n%i", *(pAux + i));

Here is a corrected and improved version of your program:

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

/* Calcula tamanho de um vetor estatico */
#define sizeofvec(a)   (sizeof(a)/sizeof(a[0]))

int * uniao( int * v1, int n1, int * v2, int n2 )
{
    int i = 0;

    /* Aloca dinamicamente v3 */
    int *v3 = malloc((n1 + n2) * sizeof(int));

    /* Preenche o vetor com o v1 */
    for( i = 0; i < n1; i++)
        v3[i] = v1[i];

    /* Preenche o vetor com v2 */
    for( i = 0; i < n2; i++ )
        v3[n1 + i] = v2[i];

    /* Retorna uniao dos vetores */
    return v3;
}

int main(void)
{
    unsigned int i = 0;

    int v1[] = { 1, 2, 3 };
    int v2[] = { 4, 5, 6, 7, 8 };

    int * pAux = uniao( v1, sizeofvec(v1), v2, sizeofvec(v2) );

    for( i = 0; i < (sizeofvec(v1) + sizeofvec(v2)); i++)
        printf("%d ", *(pAux + i));
    printf("\n");

    free(pAux);

    return 0;
}

Output:

1 2 3 4 5 6 7 8

If you want to go a little further, here's another version of the same program:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Calcula tamanho de um vetor estatico */
#define sizeofarr(a)   (sizeof(a)/sizeof(a[0]))

void uniao( int **v3, int *n3, int *v1, int n1, int *v2, int n2 )
{
    /* Calcula tamanho de v3 */
    *n3 = n1 + n2;

    /* Aloca dinamicamente v3 */
    *v3 = malloc( (*n3) * sizeof(int) );

    /* Preenche o vetor com o v1 */
    memcpy( *v3,  v1, sizeof(int) * n1 );

    /* Preenche o vetor com v2 */
    memcpy( (*v3) + n1, v2, sizeof(int) * n2 );
}

int main(void)
{
    int i = 0;
    int n = 0;
    int * pAux = NULL;

    int v1[] = { 1, 2, 3 };
    int v2[] = { 4, 5, 6, 7, 8 };

    /* Ponteiro Auxiliar recebe v3 */
    uniao( &pAux, &n, v1, sizeofarr(v1), v2, sizeofarr(v2) );

    /* Exibe vetor */
    for( i = 0; i < n; i++)
        printf("%d ", pAux[i]);
    printf("\n");

    /* Libera memoria dinamicamente alocada */
    free(pAux);

    return 0;
}

Output:

1 2 3 4 5 6 7 8
    
02.11.2017 / 01:24
4

Probably the biggest problem is passing as a pointer something that already has a pointer. This works:

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

int* uniao(int *v1, int n1, int *v2, int n2) {
    int *v3 = malloc((n1 + n2) * sizeof(int));
    for (int i = 0; i < n1; i++) v3[i] = v1[i];
    for (int i = n1, j = 0; j < n2; i++, j++) v3[i] = v2[j];
    return v3;
}

int main(void) {
    int v1[] = { 1, 2, 3 };
    int v2[] = { 4, 5, 6 };
    int *pAux = uniao(v1, 3, v2, 3);
    for (int i = 0; i < 6; i++) {
        printf("%d\n", pAux[i]);
    }
}

See running on ideone . And in Coding Ground . Also I put it in GitHub for future reference .

One thing to think about. Who will release the memory? In this case it is leaking. The main() ? But he did not allocate, why should he be responsible for this? The basic philosophy of C is: allocated, releases. Since you can not do this within uniao , because the dynamic allocation is just to keep the object alive after it, it would have to do in the main() function and pass the pointer allocated as a parameter. This will make things easier.

    
01.11.2017 / 17:17