usuario567879
Estoy tratando de devolver un puntero de una función. Pero estoy recibiendo una falla de segmentación. Alguien por favor diga qué está mal con el código
#include <stdio.h>
int *fun();
main()
{
int *ptr;
ptr = fun();
printf("%d", *ptr);
}
int *fun()
{
int *point;
*point = 12;
return point;
}
Asigne memoria antes de usar el puntero. Si no asigna memoria *point = 12
es un comportamiento indefinido.
int *fun()
{
int *point = malloc(sizeof *point); /* Mandatory. */
*point=12;
return point;
}
También tu printf
Está Mal. Necesita desreferenciar (*
) el puntero.
printf("%d", *ptr);
^
-
Si tengo más de un valor para almacenar, ¿qué haría? ¿Si necesito asignar todo o simplemente puedo incrementar el puntero?
– usuario567879
15 de octubre de 2011 a las 1:42
-
@user567879 Necesitas
malloc
más espacio. Algo comoint *point = malloc(num_values * sizeof *point);
– cnicutar
15 de octubre de 2011 a las 6:30
-
También
int *point = calloc(num_values,sizeof(int))
será útil. Más información en thinkage.ca/english/gcos/expl/c/lib/calloc.html– tremendos
6 de agosto de 2013 a las 8:42
-
¿Es una buena práctica devolver el puntero de una función y hacer que el programa principal libere la memoria? ¿Alguna otra alternativa a esta? (solo en caso de que no sea una buena práctica)
– Mahesha Padyana
27 de julio de 2015 a las 17:32
-
@cnicutar: Sería mejor si lanzas el resultado de malloc (to int*) aunque no es necesario en C,
– Destructor
19 de agosto de 2015 a las 13:06
Aunque devolver un puntero a un objeto local es una mala práctica, no causó el kaboom aquí. He aquí por qué tienes una falla de segmento:
int *fun()
{
int *point;
*point=12; <<<<<< your program crashed here.
return point;
}
El puntero local queda fuera del alcance, pero el verdadero problema es quitar la referencia a un puntero que nunca se inicializó. ¿Cuál es el valor del punto? Quién sabe. Si el valor no se asignó a una ubicación de memoria válida, obtendrá un SEGFAULT. Si por suerte se asignó a algo válido, entonces simplemente corrompiste la memoria al sobrescribir ese lugar con tu asignación a 12.
Dado que el puntero devuelto se usó de inmediato, en este caso podría salirse con la suya devolviendo un puntero local. Sin embargo, es una mala práctica porque si ese puntero se reutilizó después de que otra llamada de función reutilizó esa memoria en la pila, el comportamiento del programa no estaría definido.
int *fun()
{
int point;
point = 12;
return (&point);
}
o casi idénticamente:
int *fun()
{
int point;
int *point_ptr;
point_ptr = &point;
*point_ptr = 12;
return (point_ptr);
}
Otra mala práctica pero un método más seguro sería declarar el valor entero como una variable estática, y luego no estaría en la pila y estaría a salvo de ser utilizado por otra función:
int *fun()
{
static int point;
int *point_ptr;
point_ptr = &point;
*point_ptr = 12;
return (point_ptr);
}
o
int *fun()
{
static int point;
point = 12;
return (&point);
}
Como han mencionado otros, la forma “correcta” de hacer esto sería asignar memoria en el montón, a través de malloc.
-
Y
free()
después de su uso.– C–
3 de octubre de 2018 a las 6:38
-
usará
static
causar advertencias de compilación?– usuario12211554
14 de julio de 2019 a las 21:46
Varun Changani
No está asignando memoria en la asignación del valor 12 al puntero entero. Por lo tanto, se bloquea, porque no encuentra ninguna memoria.
Puedes probar esto:
#include<stdio.h>
#include<stdlib.h>
int *fun();
int main()
{
int *ptr;
ptr=fun();
printf("\n\t\t%d\n",*ptr);
}
int *fun()
{
int ptr;
ptr=12;
return(&ptr);
}
-
¿No existe 12 solo en la pila de esa llamada de función? Eso parece que produciría un comportamiento indefinido.
– escapar
3 de noviembre de 2017 a las 20:22
manos inactivas_94
Que yo sepa, el uso de la palabra clave new hace relativamente lo mismo que malloc (tamaño del identificador). El siguiente código demuestra cómo usar la palabra clave new.
void main(void){
int* test;
test = tester();
printf("%d",*test);
system("pause");
return;
}
int* tester(void){
int *retMe;
retMe = new int;//<----Here retMe is getting malloc for integer type
*retMe = 12;<---- Initializes retMe... Note * dereferences retMe
return retMe;
}
La pregunta más importante cuando se trata de punteros es: Puntero a ¿qué? ¿Un objeto local? Kabum. ¿Un objeto asignado dinámicamente? ¿Liberado por quién? ¿Algún objeto almacenado en otro lugar? Entonces, ¿cuánto tiempo vive ese objeto y cuánto tiempo es válido mi puntero? Devolver un puntero desde una función está especialmente lleno de riesgos, porque el puntero se inicializa en una pieza de código totalmente diferente (que a menudo ni siquiera es visible para la persona que llama), y las personas que llaman no saben cómo tratar el resultado. Una buena documentación para tales funciones es muy importante.
– sbi
13 de octubre de 2011 a las 13:47
Solo recuerde siempre malloc cualquier objeto, puntero y estructura de datos. si no lo hace, siempre obtendrá una falla de segmentación porque simplemente dice que no le estamos asignando ningún espacio.
–Kevin
13 de octubre de 2011 a las 14:07
Cuando “cambia el error en el código”, hace que la respuesta (parcialmente) no esté relacionada con la pregunta. El código en cuestión no es perfecto, ese es el motivo de la pregunta. Recomiendo encarecidamente evitar corregir cualquier código en las preguntas.
– arpista
30 de mayo de 2014 a las 17:29
Hola, cual es la diferencia entre hacerlo a traves de
malloc
y hacerlo como*ptr = 12
? ¿Por qué el primero devuelve un puntero válido a la persona que llama incluso cuando se declara localmente dentro del remitente, mientras que el último no lo hace?– Bestia Sexy
03/10/2015 a las 12:30
@ActitudMonger Porque
malloc
dice “Quiero algo de memoria para almacenar cosas”, pero simple y llanamente*ptr = 12
dice “Quiero algo de memoria para hacer un cálculo, que pueda usarse para otras cosas más adelante”.– wizzwizz4
09/04/2016 a las 10:46