2010-11-21 13 views
0
gcc 4.5.1 c89 

Aşağıdaki yapının elemanları atayan bir işlevi vardır:Bir işlevde bir hata varsa ne dönecek?

static struct Config_t { 
    char protocol[LINE_SIZE]; 
    char mode[LINE_SIZE]; 
} *app_config = NULL; 

atayabilir ve hafızayı temizlemek için malloc ve memset kullanılarak fonksiyonu. İşte

char* get_mode() 
{ 
    if(app_config->mode != NULL) { 
     return app_config->mode; 
    } 
    return NULL; 
} 

Ben bir değer atanmış olduğunu kontrol ediyorum: Tamamlandığında

, ben bireysel unsurları alır işlevlere sahiptir. Ve değilse NULL döndürüyor. Yani arama işlevinde bir NULL döndürülmüş olup olmadığını kontrol edebilirim. Ancak, bunu yapmak için daha iyi bir yolu var mı? Orada iyi durumda olduğuna çok hata koşulu için NULL dönen tüm öneriler için

çok teşekkür ederiz, C

+3

C ile pratik yapıyorum ama 'mode' 'NULL' olamaz, değil mi? 'app_config' kesinlikle 'NULL' olabilir, ancak 'mode 'diziniz, bir işaretçi olarak değil, yapının içsel bir parçası olarak tanımlanır. Yapıya sahip olacaksınız veya yapamayacaksınız, ancak yapının * parçası * olmayacak. Eğer 'mode' 'char * mode' olarak tanımlandıysa, bu farklı olurdu. –

+2

sadece şu modu döndürür: 'return app_config-> mode;' kontrol etmeden. – khachik

+0

@ T.J Modu bir dizidir. Ancak, bu bir işaretçiye dönüşecek. Mod öğesi, örneğin herhangi bir değer atanmamışsa ne döneceğimi merak ediyordum. Teşekkürler. – ant2009

cevap

3

, işaretçileri dönen fonksiyonlar için standart bir uygulamadır. Ayrı


(. Işaretçileri dönüş yok işlevler için olağan kongre başarı ve hata sıfırdan farklı hata kodu 0 döndürmektir), ve belki biraz konu dışı: mode kutu' Olsa, NULL olmak, olabilir mi? app_config kesinlikle NULL olabilir, bu bir yapının bir işaretçisidir, ancak mode, bir işaretçi olarak değil, yapının içsel bir parçası olan bir dizi olarak tanımlanır. Yapıya sahip olacaksınız veya yapamayacaksınız, ancak yapının yalnızca bölüm'una sahip olmayacaksınız. Sadece yapının hafızasını ayırmak mode için LINE_SIZE chars tahsis edecektir; Aslında, sizeof(struct Config_t) == LINE_SIZE + LINE_SIZE, yapısında bir dizi karakter ve ardından başka bir karakter dizisidir. İlgili bir işaretleyici yok (app_config'dan başka, çünkü bunu yapının işaretçisi olarak tanımladınız). Sonuç

, tamamen sizin struct Config_t, sadece bunu tahsis etmek:

app_config = malloc(sizeof(*app_config)); 

(. Veya app_config = malloc(sizeof(struct Config_t)); Platformunuz yukarıda izin vermez ise) Yani mode ayırır, başka bir şey gerekli. mode bir char * olarak tanımlandı

, bu farklı olacaktır:

static struct Config_t { 
    char *protocol; 
    char *mode; 
} *app_config = NULL; 

Şimdi sizeof(struct Config_t) == 2 * sizeof(void*) (aşağıya bakınız), yapının kendisi iki işaretçiler oluşur, bunlar işaret edebilir herhangi bir veri. Yapının tahsis edilmesi değil, onlar için herhangi bir depolama ayırır.

#include <stdio.h> 

#define LINE_SIZE (200) 

struct Config_t { 
    char protocol[LINE_SIZE]; 
    char mode[LINE_SIZE]; 
}; 
struct Config_t_with_pointers { 
    char *protocol; 
    char *mode; 
}; 

int main(int argc, char* argv[]) 
{ 
    printf("sizeof(struct Config_t) = %zu\n", sizeof(struct Config_t)); 
    printf("sizeof(struct Config_t_with_pointers) = %zu\n", sizeof(struct Config_t_with_pointers)); 
    return 0; 
} 

(sizin derleyici göz önüne alındığında, herhangi yeni gcc iddia ettiği gibi [ve C99 standardında var Matthew söyler], size_t bağımsız değişkenler için z Biçim belirteci kullanmakta serbest hissetti.)

Çıkış (benim 64 bit Linux sistemi): Böyle (alır gibi, C fonksiyonları inşa tanımına) dayanarak

sizeof(struct Config_t) = 400 
sizeof(struct Config_t_with_pointers) = 16
+0

T. J., yukarıdaki yorumunuz doğru, bu yüzden burada bahsederim. Geçerli bir 'Config_t' zamanınız varsa, içinde bir mod diziniz var. –

+0

@Matthew: Teşekkürler; yapılır. –

+0

J., 'size_t' standart C (C99) 'dur. –

1

, NULL dönen olduğunu belirtmek için ideal bir yoldur o bir ödev veya tahsis yapmak mümkün değildi.

+4

'gets', API tasarımı için gerçekten iyi bir model değil ... –

+0

@Matthew: LOL !! –

+0

Şimdi anladığınızı anlıyorum. Sanırım, bunun için bir sürü dezavantajı var doğru mu? Demek istediğim, bazı C derleyicilerinde uyarı alırız,() tehlikeli bir işlevdir :) –

1

Bunun gerçekleşmesinin tek nedeni (bir değer atanmamışsa), aralarında ayrım yapmak için birden fazla değere gerek yoktur. Ayrıca, NULL geçerli bir işaretçi değil, bu yüzden yanlış bir şey göremiyorum.

Daha fazla hata yaptıysanız, errno.h bu amaçla kullanabilirsiniz.

İlgili konular