2015-06-26 2 views
3

Я знаю, что вы можете вернуть тип указателя из функции. ex. void *foo() Можете ли вы вернуть тип указателя на указатель в функции? ex. void **foo2()Можете ли вы вернуть тип указателя на указатель в функции?

Вот подробнее о моем вопросе:

Я пытаюсь назначить PTR к PTR, tmp2, к блокам [I] [J], а затем вернуться tmp2. блоки [i] [j] также являются ptr-to-ptr.

Я смущен, чтобы манипулировать ptr ptr-to-ptr: Я не уверен, что return ((tmp2+i)+j); является причиной ошибки сегментации по строке printf("2---%d\n", **tmpPtr2);. Для отладки я пытаюсь напечатать: printf("%d\n", *((*(tmp2+i)) +j)); Однако это вызывает новую ошибку сегментации.

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

int **blocks, **tmp2; 
int n = 10; 

int **findBlock2(int b){ 
    int i, j ; 

    for (i=0; i<n; i++){ 
     for (j=0; j<n; j++){ 
      if (blocks[i][j]==b){ 
       printf("%d\n", blocks[i][j]); 

       //Segmentation fault 
       printf("%d\n", *((*(tmp2+i))+j)); 

       return ((tmp2+i)+j); 
      } 
     } 
    } 
    return NULL; 
} 

int main(int argc, const char * argv[]) { 
    int i, j; 
    int **tmpPtr2; 

    //allocate memory space and assign a block to each index 
    blocks=malloc(n * sizeof *blocks); 
    for (i=0; i<n; i++) { 
     blocks[i]=malloc(n * sizeof(*blocks[i])); 
     blocks[i][0]=i; 
    } 

    if ((tmpPtr2=findBlock2(4))==NULL) return -1; 

    //Segmentation Fault 
    printf("2---%d\n", **tmpPtr2); 

    return 0; 
} 

Update, чтобы ответить на мой вопрос:

(1) Добавление т tmp2=blocks; к началу findBlock2() удалены обе ошибки сегментации.

(2) return ((tmp2+i)+j); показано, как манипулировать PTR-к-PTR, указывающую на PTR к PTR или 2D массива

(3) printf("%d\n", *((*(tmp2+i)) +j)); показывает, как это сделать (2) и разыменовать него.

Надеется, что это помогает другим

+0

Да, попробуйте. – Jens

+0

Вы на самом деле имеете в виду указатель на указатель функции? или это ответы на ваши вопросы? – AndrewGrant

+1

Ответ да, но у вас, вероятно, есть связанная с этим проблема кодирования, которую вы пытаетесь решить, так что опубликуйте свой код и конкретную проблему, и вы получите гораздо лучший ответ, чем просто Да +, несколько примеров, которые скорее всего, не имеют отношения к вашей проблеме. –

ответ

1

Да, так же, как вы бы с любым переменным указателем.

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

int ** function(){ 
    int ** matrix = malloc(sizeof(int*)); 
    *matrix = malloc(sizeof(int)); 
    matrix[0][0] = 5; 
    return matrix; 
} 

int main() 
{ 
    int **matrix = function(); 
    printf("%d",matrix[0][0]); 
    free(matrix[0]); 
    free(matrix); 
    return 0; 
} 

Добавление в другую часть. В вашей функции findBlock2, помимо доступа к недопустимой ссылке, которая уже была указана, кажется, что ваша цель - вернуть ссылку на блок, который выполняет оператор if. Если это так, то достаточно указать указатель на int*.

int *findBlock2(int b)

///////////////// 

return (*(blocks+i)+j);

0

Ответ "да". Пожалуйста, обратитесь следующий код:

#include <stdio.h> 
#include <malloc.h> 

void ** foo2(void){ 
    int **p = malloc(sizeof(*p)); 
    return (void**)p; 
} 

int main(void) { 
    printf("%p\n", foo2()); 
    return 0; 
} 

Результат есть (в моей 32-bit платформе):

0x80e9008 
+1

'return (void **) p' не переносится,' void ** 'не является общим типом указателя типа' void * '. Он должен просто вернуть' void * ', а затем код вызова может отличать его до 'int **' перед разыменованием. –

+0

@MattMcNabb: «return (void **) p не переносится», не могли бы вы дать какой-либо экзамен Плес? Я действительно не знаю эту проблему, спасибо большое! –

+0

'int *' и 'void *' могут иметь разный размер и представление (в современных системах это не так, но я использовал тот, где он был), поэтому притворяясь, что указатель указывает на 'void *', когда он фактически указывает на 'int *', не будет получать разумный указатель –

0

Вы, вероятно, хотите 2D массив в не какой-то медленный, фрагментированной таблицы перекодировки. В этом случае выполните следующие действия:

#include <stdlib.h> 

void* alloc_2D (size_t x, size_t y) 
{ 
    return malloc (sizeof (int[x][y])); 
} 

int main (void) 
{ 
    const size_t X = 5; 
    const size_t Y = 3; 

    int (*arr_2D)[Y] = alloc_2D(X, Y); 

// X dimension was omitted in declaration to make array syntax more intuititve: 

    arr_2D[i][j] = something; 

    ... 
    free(arr_2D); 
}