Pregunta

Quiero almacenar una cadena en la memoria y leerla más tarde:

$->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

Aunque la línea B y la línea D muestran la misma dirección, el printf en la línea C falla con una falla de segmentación. ¿Qué me estoy perdiendo?

¡Cualquier ayuda sería realmente apreciada!

¿Fue útil?

Solución

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

Eso no es válido. A medida que muestra la línea anterior a ella que constante es en realidad un puntero, no puede tratarla como si fuera del tipo int . No necesariamente tienen el mismo tamaño y alineación. Use el formato utilizado para void * . Producirá direcciones de memoria correctamente:

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

Otros consejos

  1. siempre verifique el valor de retorno de malloc .
  2. sprintf - > snprintf
  3. "% f " - > "%.*g"

Aquí hay un ejemplo:

/** $ 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;
}

Salida:

number: 12345678901234567000.000000 1.23456789012346e+19

¿Quizás entre el tiempo de las dos piezas de código que tiene desde free d la cadena?

$->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

Dado que el programa está produciendo una falla de segmentación, creo que el problema es más probable que la estructura designada (señalada) por expr- > desc.constant se haya reutilizado desde que el espacio fue asignado, o posiblemente el espacio nunca fue realmente asignado en absoluto.

El código exhibe varios pecados veniales, como usar sprintf () en lugar de snprintf () , y asignar gratuitamente 200 bytes para la representación de cadena de un número de coma flotante . (Es muy poco probable que necesite tanto espacio; si lo hace, probablemente debería permitir al menos 100 dígitos más de los que tiene, ya que el rango de exponente para números de coma flotante es generalmente +/- 308, y la única razón por la que Necesitaría 200 caracteres para permitir números increíblemente grandes o increíblemente pequeños).

Ha demostrado que $$ - > desc.constant apunta al mismo lugar, pero no ha mostrado cómo se asigna ese espacio. Luego asigna el espacio de cadena en $$ - > desc.constant- > base.id , sin asignar claramente el espacio para base .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top