2016-03-01 7 views
1
/* 
//i comment this block, please see the updates 
void* fun_one(char *buffer, long length) 
{ 
    if(NULL == buffer) 
     return xxx; //return what value here 
    ... 
} 

fun_two() 
{ 
    ... 
    fun_one(image->buffer, image->length); 
    ... 
} 
*/ 

Если произошла ошибка, я не надеюсь выйти из программы, но вернуться к fun_two(). Что мне делать? Я знаю, что return (void *)0; или return NULL; при успешном завершении, но верните какое значение при ошибке?return what when error in void * fun()

ссылки, связанные: void *


обновление:

но что, если Ти функции нити, такие как

int main() 
{ 
    ... 
    pthread_create(&id1, NULL, (void*)myThread1, &param_struct); 
    ... 
} 

void* myThread1(void* param) 
{ 
    struct len_str* img = (struct len_str*)param; 
    if(NULL == img->buf) 
     return xxx; //return what value here 
    if(0 == img->len) 
     return xxx; 
    ... 
} 

Ссылки по теме: pthread_create

т он вернется значение myThread1() является void * , какое значение должно вернуться, если ошибка происходит

+3

Вы можете написать 'void * res = fun_one (...);' и проверить значение 'res'. – purplepsycho

+2

Это зависит от вас. Почему вы хотите вернуть 'void *'. Я бы просто вернул «int». –

+0

@MichaelWalz, но что, если это функция потока, такая как 'pthread_create (& id1, NULL, (void *) myThread1, NULL); ' – kgbook

ответ

0

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

Затем, когда вы вызываете pthread_join, вы получите указатель на эту переменную, которую вы затем произнесите и разыщите, чтобы прочитать значение, и free, когда вы закончите.

void* myThread1(void* param) 
{ 
    int *rval = malloc(sizeof(int)); 
    if (rval == NULL) { 
     perror("malloc failed"); 
     exit(1); 
    } 
    struct len_str* img = (struct len_str*)param; 
    if(NULL == img->buf) { 
     *rval = 0; 
     return rval; 
    } 
    if(0 == img->len) { 
     *rval = 1; 
     return rval; 
    } 
    ... 
} 


int main() 
{ 
    ... 
    pthread_create(&id1, NULL, (void*)myThread1, &param_struct); 
    ... 
    void *rval; 
    pthread_join(id1, &rval); 
    printf("rval = %d\n", *(int *)rval); 
    free(rval); 
} 
+0

прототип: 'int pthread_join (pthread_t thread, void ** retval);', Is 'void * rval; pthread_join (id1, &rval);' равно void ** rval; pthread_join (id1, rval); '? thanks – kgbook

+0

@CoryKang Это * не * то же самое. В первом случае вы проходите * адрес * переменной, которая «pthread_join» затем разыскивает и заполняет. Во втором случае вы передаете * значение * переменной, которая не была инициализирована, поэтому 'pthread_join' попытается использовать эту неинициализированную переменную как адрес и разыменовать его, скорее всего, вызвав segfault. – dbush

+0

'void ** rval = malloc (4); pthread_join (id1, rval);', то это то же самое? – kgbook

3

Вместо того, чтобы возвращать указатель, возвращают значение int типа.

Возврат 0 означает все в порядке.
Возврат 1 означает, что указатель NULL прошел.
Возврат 2 означает недопустимую длину.
...

int fun_one(char *buffer, long length) { 
    if (buffer == NULL) return 1; 
    if (length == 0) return 2; 
    if (length < 0) return 3; 
    /* ... */ 
    return 0; 
} 

Для дополнительной ясности (???), вы можете использовать перечисления

enum fun_one_errors {FO_OK, FO_NULL, FO_ZERO, FO_NEG}; 
return FO_ZERO; 
+0

Возможно, мое описание не было хорошим, я обновляю вопрос. – kgbook

2

вы боретесь с "дизайном" ваш интерфейса. Что вам нужно, чтобы перейти к функции, что ей нужно вернуть и как вы сигнализируете об ошибке.

Обычно, если вы возвращаете указатель, значение нуля указателя (NULL) означает ошибку. Если вы хотите передать дополнительную информацию, вы можете использовать вспомогательную переменную, установленную на один из кодов ошибок. Это будет глобальным переменным или (указатель) переменный:

int my_errcode; 
... 
if ((p=fun_one(buf, len))==NULL) printf("error %d\n",my_errcode); 

В качестве альтернативы, вы возвращаете пустоту * указатель в качестве параметра (вы должны использовать двойную косвенность сейчас), и пусть функцию обратного сигнала успех или неудача и тип отказа:

if ((my_errcode=fun_one(buf, len, &p))!=0) printf("error %d\n",my_errcode); 

Так что до вас ...

+0

Да, ваш ответ абсолютно прав. Однако если функция является функцией потока, то тип возвращаемого значения будет 'void *' – kgbook

0

Ну, при возвращении указателя у вас обычно возникает проблема, что делать, если при выполнении функции возникла ошибка?

Классический подход заключается в резервировании специального значения (NULL или 0 в C++) для представления такого рода ошибок и использования глобального представления различных значений ошибок, которые могут возникнуть.

Но, если вы хотите, чтобы модуль повторного ввода мог многопоточно? Ну, у указателей есть проблема, что везде, где они указывают, является возможным источником проблем, если это место занято бесполезной переменной.

Но у нас есть другой подход. Просто создайте немые переменные (не используемые ни для чего другого) для хранения адресов ничего. Таким образом вы можете зарезервировать несколько значений указателя (адреса этих переменных) для представления правильных кодов ошибок. Поскольку места, которые они размещают компилятором, не могут использоваться ни для чего другого, их можно использовать для хранения (не для хранения) адреса чего-то особенного для вас.

int error_001_placeholder; 
int error_002_placeholder; 
int error_003_placeholder; 

... 

if (condition_1) return &error_001_placeholder; 
if (condition_2) return &error_002_placeholder; 
if (condition_3) return &error_003_placeholder; 

Тогда вы будете иметь возможность проверить различные недействительных возврат указателей, просто проверяя, если они принадлежат к этому набору указателей.

Даже больше, если вы хотите сделать общую проверку ошибок, вы можете заказать глобальный массив и возвращаете отдельные ячейки для различных ошибок, наконец, к общей проверке, если возвращенное значение ошибка, вы можете просто проверить, если returned_value >= errors_array && returned_value < errors_array + erros_array_size ,