2016-02-15 4 views
1

Je voudrais copier 4 octets de unsigned int vers un tableau char non signé. Une fois exécuté la fonction suivante get_result va à la segmentation faute:memcpy unsigned int à unsigned char segmentation fault

int exec_cmd(unsigned int * apu32Var) 
{ 
    int ret = -1; 
    char cmd[100] = { 0 }; 
    char resp[100] = { 0 }; 

    sprintf(cmd, "%s %s", "/home/send_frames.sh", "read"); 
    ret = exec_cmd_ret_result(cmd, resp); 

    if(apu32Var != NULL) 
    { 
     *apu32Var = (((unsigned int)resp[0]) <<24)+(((unsigned int)resp[1]) <<16)+(((unsigned int)resp[2]) <<8)+(unsigned int)resp[3]; 
    } 
    return ret; 
} 

int get_result(unsigned char * buffer, unsigned short * size) 
{ 
    unsigned int u32Var = 0; 

    exec_cmd(&u32Var); 

    memcpy(buffer, &u32Var, sizeof(unsigned int)); 
    *size += sizeof(unsigned int); 
    return 0; 
} 


int main(int argc, char **argv) 
{ 
    unsigned char *buf; 
    unsigned short *size; 

    get_result(buf+4, size); 

    return 0; 
} 

Cependant, en ce qui concerne à la page man memcpy() il semble memcpy() sont bien gérées. Qu'est-ce qui ne va pas?

+1

Vous ne nous montrez pas la partie où 'Test_result' est appelée. Et que dit votre débogueur? –

+0

@ M.M Désolé, j'ai inclus plus de détails dans la question – ogs

+0

Quel est le nom du compilateur sous-standard qui ne vous avertit pas que 'buf' est utilisé non initialisé dans' main() '? – Jens

Répondre

2

En supposant que votre appel à test_result réellement devrait appeler get_result, alors vous avez deux gros problèmes. Le premier et le plus grave est que vous transmettez des variables locales non initialisées comme arguments à la fonction. Les variables locales non initialisées ont des valeurs indéterminées. Pour un pointeur, cela signifie qu'il peut pointer à peu près n'importe où, et essayer de le déréférencer mènera à undefined behavior. Vous devez réellement faire pointer ces pointeurs quelque part pour que cela fonctionne. Cela vaut pour les deux variables.

Le deuxième problème est que vous ne comprenez pas comment fonctionne le renvoi par référence en C. Oui, la fonction doit prendre un pointeur, mais vous ne devriez pas créer de variable pointeur et passer à la fonction. Au lieu de cela, vous devez utiliser l'opérateur address-of & sur une variable sans pointeur.

Pour résoudre les problèmes, votre code devrait ressembler à

unsigned char buf[256] = { 0 }; // Arbitrary size, all initialized to zero 
unsigned short size = 0; // To make sure it's properly initialized 

get_result(buf + 4, &size); // Note use of & to pass a pointer to the variable size 

Notez que cela fonctionne à l'aide d'un tableau, puisque les tableaux désintègre naturellement à des pointeurs vers son premier élément.

1

buf dans main n'est jamais initialisé, donc il pointe vers un emplacement aléatoire dans la mémoire. C'est un comportement indéfini et une recette parfaite pour une erreur de segmentation.

De même, *size est lu à partir de lorsque vous utilisez +=, mais la valeur n'a jamais été initialisée dans main, donc votre déréférence une valeur indéfinie.

Vous devez déclarer buf comme un tableau de taille suffisante et passer qu'en outre, déclarer size comme int, l'initialiser à 0, et transmettre son adresse.

int main(int argc, char **argv) 
{ 
    unsigned char buf[100]; 
    unsigned short size = 0; 

    // I'm assuming this was a typo and you ment to call get_result instead of test_result 
    get_result(buf, &size); 

    return 0; 
} 
+0

@ M.M Merci. Édité. – dbush