Question

Je veux stocker une chaîne en mémoire et la lire plus tard:

$->desc.constant->base.id =  (char*)malloc(200);
sprintf($->desc.constant->base.id, "%f", $1);
printf("->%s\n", $->desc.constant->base.id); //LINE A
printf("->%i\n", $->desc.constant); //LINE B

//SOME OTHER CODE

//Then, later on in a function call:

printf("%i", expr->desc.constant); // LINE D
printf("%s", expr->desc.constant->base.id); // LINE C

Bien que la ligne B et la ligne D affichent la même adresse, l’impression dans la ligne C échoue avec une erreur de segmentation. Qu'est-ce qui me manque?

Toute aide serait vraiment appréciée!

Était-ce utile?

La solution

printf("->%i\n", $->desc.constant); //LINE B

C'est invalide. Comme vous indiquez à la ligne précédente que constant est en fait un pointeur, vous ne pouvez pas le traiter comme s'il s'agissait du type int . Ils n'ont pas nécessairement la même taille et le même alignement. Utilisez le format utilisé pour void * . Il émettra correctement les adresses de mémoire:

printf("->%p\n", (void*)$->desc.constant); //LINE B

Autres conseils

  1. toujours vérifiez la valeur de retour de malloc .
  2. sprintf - > snprintf
  3. "% f " - > "%. * g"

Voici un exemple:

/** $ gcc print_number.c -o print_number */
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>


int main(int argc, char *argv[])
{
  const char* number_format = "%.*g";
  const int ndigits = 15;
  assert(ndigits > 0);
  const int maxlen = ndigits + 8 /* -0.e+001, Infinity */ + 1 /* '\0' */;

  char *str = malloc(maxlen);
  if (str == NULL) {
    fprintf(stderr, "error: malloc\n");
    exit(1);
  }    

  double number = 12345678901234567890.123456789012345678901234567890;
  /** `number = 0/0` crashes the program */;

  printf("number: %f\t", number);

  int len_wouldbe = snprintf(str, maxlen, number_format, ndigits, number);
  assert(len_wouldbe < maxlen);

  printf("%s\n", str);
  return 0;
}

Sortie:

number: 12345678901234567000.000000 1.23456789012346e+19

Peut-être qu'entre le temps des deux morceaux de code que vous avez depuis free d la chaîne?

$->desc.constant->base.id =  (char*)malloc(200);
sprintf($->desc.constant->base.id, "%f", $1);
printf("->%s\n", $->desc.constant->base.id); //LINE A
printf("->%i\n", $->desc.constant); //LINE B

//SOME OTHER CODE
// which happens to do
free($->desc.constant->base.id);

printf("%i", expr->desc.constant); // LINE D
printf("%s", expr->desc.constant->base.id); // crash

Étant donné que le programme génère une erreur de segmentation, je pense que le problème est probablement que la structure désignée par expr- > desc.constant a été réutilisée depuis la suppression de l'espace. alloué, ou éventuellement l’espace n’a jamais vraiment été alloué.

Le code présente divers péchés véniels, tels que l'utilisation de sprintf () au lieu de snprintf () et l'allocation gratuite de 200 octets pour la représentation sous forme de chaîne d'un nombre à virgule flottante . (Il est très peu probable que vous ayez besoin de cet espace. Si vous le faites, vous devez prévoir au moins 100 chiffres de plus que ce que vous avez, car la plage de l’exposant pour les nombres à virgule flottante est généralement de +/- 308, et vous seul Il me faudrait 200 caractères pour permettre des nombres incroyablement grands ou incroyablement petits.)

Vous avez montré que $$ - > desc.constant pointe vers le même endroit, mais vous n'avez pas montré comment cet espace est alloué. Vous allouez ensuite l'espace de chaîne dans $$ - > desc.constant- > base.id , sans allouer clairement l'espace pour base .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top