2016-06-21 4 views
2

Я пытаюсь вернуть 4 указателя, которые хранятся в другом указателе от функции в C, но я получаю ошибку сегментации. Кто-нибудь знает, как это сделать?Возврат нескольких указателей из функции

Вот так я пытался сделать это:

//declaration of 5 pointers (int * ptr0, float * ptr1, ..., int * ptr4) 

int * function() 
{ 
    int * ptr; 
    ptr = malloc(sizeof(int)*4); 

    float * ptr1; 
    ptr1 = malloc(sizeof(float)*4); 

    float * ptr2; 
    ptr2 = malloc(sizeof(float)*4); 

    float * ptr3; 
    ptr3 = malloc(sizeof(float)*4); 

    int * ptr4; 
    ptr4 = malloc(sizeof(int)*4); 

    retunr ptr; 
} 

ptr0 = function(); 
ptr1 = ptr0[0]; 
ptr2 = ptr0[1]; 
//and so on... 

Хорошо, я изменил свою программу, но теперь я не могу писать указатели больше. Я знаю, что это действительно «глупый» вопрос, но я действительно не знаю. Может кто-нибудь помочь?

+0

, если вы хотите вернуть несколько значений, вы можете вернуть структуру или вернуть их через список параметров – iedoc

+0

Пожалуйста, покажите весь код, включая декларации. – s7amuser

+0

Возможный дубликат: http://stackoverflow.com/questions/9144516/out-parameters-in-c –

ответ

4
void ** function() 
{ 
    void ** ptr; 
    ptr = (void **)malloc(sizeof(void *)*4); 

    ptr[0] = malloc(sizeof(float)*4); 
    ptr[1] = malloc(sizeof(float)*4); 
    ptr[2] = malloc(sizeof(float)*4); 
    ptr[3] = malloc(sizeof(int)*4); 

    return ptr; 
} 
+0

Im, собирающийся проверить это – noName

+1

@noName остерегайтесь, что 'ptr0 [x]' являются ** void ** указателями. вам нужно будет бросить их для работы с 'int'a и' float's – mvidelgauz

+1

Не нужно бросать в C. – alk

1

Вы не заполнили * ptr, но даже если вы это сделали, не делайте этого. Используйте std::tuple<> или пару std::pair<> s - или верните структуру.

Редактировать: поскольку это больше не C++, просто верните структуру с четырьмя полями.

+0

', так как он больше не C++, просто верните структуру с четырьмя полями.« Я бы сердечно порекомендовал и на C++ , потому что вы можете дать описательные имена для членов. – user2079303

+0

@ user2079303: в C++ вы просто скажете std :: tie (ptr1, ptr2, ptr3, ptr4) = function(), но в остальном я согласен. – lorro

8

Вы можете вернуть только одно значение из функции. Простое решение - вернуть структуру, содержащую нужные указатели.

struct pointers { 
    float* ptr1; 
    float* ptr2; 
    float* ptr3; 
    // or perhaps an array instead: 
    // float* f_ptrs[3]; 
    int* ptr4; 
} 

struct pointers function() { 
    struct pointers p; 
    // initialize the members here 
    return p; 
} 
2

Есть три варианта, вы можете вернуть void** (в основном, это указатель на массив void*, который вы затем CAST), вы можете объявить структуру, которая содержит указатели, а затем выделить и возврат указатель на такую ​​структуру (то пусть вызывающий де-выделить-структуру), или вы можете использовать func(float **ptr0, float **ptr1, float **ptr2, int **ptr3) и присвоить malloced памяти *ptr0 ...

ни один из них совершенны, в зависимости от обстоятельств, я бы выбрал либо решение 2, либо решение 3, исходя из того, что это происходит чтобы в конечном итоге беспорядочно помнить все релевантные роли и позволить компилятору помочь вам с типами - хорошая идея.

1

я видел, что это не было упомянуто, но вы можете также передать двойные указатели на функции и есть функция заполнить их, еще один способ вернуть несколько значений:

void function(int** p1, float** p2, float** p3, float** p4, int** p5) 
{ 
    *p1 = malloc(sizeof(int)*4); 

    *p2 = malloc(sizeof(float)*4); 

    *p3 = malloc(sizeof(float)*4); 

    *p4 = malloc(sizeof(float)*4); 

    *p5 = malloc(sizeof(int)*4); 
} 

int* ptr1; 
float* ptr2; 
float* ptr3; 
float* ptr4; 
int* ptr5; 

function(&ptr1, &ptr2, &ptr3, &ptr4, &ptr5); 
+3

Не нужно бросать в C. – alk

+2

литье может скрыть ошибку, которую компилятор поймал бы в отсутствие отливки – pmg

+0

ах мой плохой, я обычно работаю с C++, я удалю кастинг, спасибо – iedoc

1

Что по этому поводу:

#include <stdlib.h> 
#include <stdio.h> /* for perror() */ 


int function(void ** ptrs, size_t n) 
{ 
    int result = -1; 

    pptrs[0] = malloc(...); 
    if (NULL == ptrs[0]) 
    { 
    goto err; 
    } 

    ... 

    ptrs[n - 1] = malloc(...); 
    if (NULL == ptrs[n - 1]) 
    { 
    goto err; 
    } 

    result = 0; 

err: 

    return result; 
} 

int main(void) 
{ 
    size_t n = 5; 
    void * ptrs[n]; 
    for (size_t i = 0; i < n; ++n) 
    { 
    ptrs[n] = NULL; 
    } 

    if (-1 == function(ptrs, n)) 
    { 
    perror("function() failed"); 
    exit(EXIT_FAILURE); 
    } 

    /* Do stuff. */ 

    /* Free memory where ptrs' are pointing to. */ 

    return EXIT_SUCCESS; 
} 

Если Влас не поддерживается изменить начало main() быть:

#define N (5) 

int main(void) 
{ 
    size_t n = N; 
    void * ptrs[N] = {0}; 

    if (-1 == function(ptrs, n)) 
    { 
    ... 
Смежные вопросы