2013-05-14 4 views
0

Je suis en train de faire quelque chose comme ce qui suit dans C:Segfault - mais le pointeur est NULL

void *initialize() 
{ 
    my_type *ret = malloc(sizeof(my_type)); 
    return (void*)ret; 
} 

void test() 
{ 
    my_type* ret = (mytype*)initialize(); 
    my_type x = *ret; 
} 

Il se bloque sur le déréférencement avec:

Received signal 11 (Segmentation fault: 11) 

Le pointeur est non nul: J'ai essayé d'imprimer le pointeur, et j'ai eu une valeur.

J'ai aussi essayé de faire un nouveau droit de my_type dans la fonction de test, comme ceci:

my_type* new = malloc(sizeof(my_type)); 

Lorsque j'imprime les représentations entières de nouvelles et ret, ils sont des entiers très proches les uns des autres. Donc, ces choses devraient être à proximité dans la mémoire.

+1

'printf' a besoin d'un spécificateur de format Quel est le type de 'mytype-> field'? –

+0

Quelle est la valeur de 'mytype-> field'? – Barmar

+0

Quel est le type de 'field' – MOHAMED

Répondre

2

Si le compilateur ne connaît pas une fonction, il considère int comme son type de retour.

Si la taille de int est différente de celle retournée par la fonction, le code généré par le compilateur risque de ne pas renvoyer le nombre d'octets correct.

Toutefois, le code que vous avez publié est correct et fonctionnera comme prévu, car initialise() se produit avant où il est utilisé, de sorte que le compilateur sait déjà quel type retourne la fonction.

La plupart propably le code d'origine (vous avez fait pas post) ressemble à quelque chose comme ça (sans le prototype de initialise()):

Effectuez les opérations suivantes:

#include <stdlib.h> /* To pull in malloc's protoype. */ 

void * initialize(void); 

void test() 
{ 
    my_type x, * ret = initialize(); 
    if (ret) 
     x = *ret; 
} 

void * initialize(void) 
{ 
    my_type * ret = malloc(sizeof(*ret)); 
    return ret; 
} 
1

Les chances sont que field soit (a) un tableau char, (b) un pointeur sur char, ou (c) une valeur entière. Oui?

Dans les trois cas, l'instruction printf() attend que field soit un pointeur vers une chaîne de caractères terminée par un caractère nul. Au moins dans l'exemple de code que vous fournissez, il n'est initialisé à rien. Donc ... le SIGSEGV est parce que (a) field est un tableau char non-initié et qui sait jusqu'où la mémoire printf() est en train de lire la recherche d'un terminateur nul, (b) le champ est un pointeur non initialisé. juste parce que ce n'est pas zéro, cela ne veut pas dire que c'est une adresse mémoire valide, ou (c) vous essayez de transmettre un entier ou une autre valeur à printf() comme un pointeur sur char, ce qui n'est pas le cas.

L'un de ces trois produira le résultat que vous signalez.

0

Selon votre commentaire, field est un int si

le

printf(mytype->field); 

devrait être

printf("%d\n", ret->field); 

De printf() page du site Cplusplus

int printf (format const char *, ...);

imprimer les données formatées à stdout

écrit la chaîne C pointée par format à la sortie standard (stdout). Si le format inclut des spécificateurs de format (sous-séquences commençant par%), les arguments supplémentaires suivants sont formatés et insérés dans la chaîne résultante en remplaçant leurs spécificateurs respectifs.

1

Il semble que vous avez 2 types avec le nom sont proches

mytype et my_type

my_type *ret = malloc(sizeof(mytype)); 

et

my_type* ret = (mytype*)initialize(); 

peut-être c'est une faute de frappe que vous utilisez 2 differents nom pour le même type. et cela peut provoquer un plantage