1
votes

Comment réparer 'adresse de la mémoire de pile associée à une variable locale' lors du retour d'une adresse de variable à partir d'une fonction?

Mon prof. m'a fait copier et coller le code ci-dessous qu'elle a écrit et cela a continué à me donner des bugs.

En exécutant son programme, la sortie était 1 pour n'importe quelle valeur.

Logiquement, je comprends comment la fonction doit renvoyer l'adresse et dans l'ensemble elle en imprime la valeur. En théorie, c'est ça.

Voici donc ce que j'ai essayé jusqu'à présent:

1) Il suffit de supprimer l'instruction p = cube (& n) et de la remplacer par:

#include <iostream>

int *cube(int *);

int main()
{
    int n, *p;
    std::cout << "Enter an int: ";
    std::cin >> n;

    p = cube(&n);

    std::cout << "Cube of " << n << " is " << *p << std::endl;

    return 0;
}

int *cube(int *number)
{
    int result = (*number) * (*number) * (*number);
    return &result;
}

Cela a fonctionné.

2) Afin de résoudre l'erreur "variable locale", j'ai fait de "result" une variable globale.

3) Dans cube (), j'ai fait:

int *cube(int *number)
{
    int result = (*number) * (*number) * (*number);
    int *newResult = &newResult;
    return newResult;
}

... mais il a produit 1 pour n'importe quel entier.

Voici l'exemple de code qu'elle a partagé. p>

    std::cout << "Cube of " << n << " is " << cube(&n) << std::endl;

Selon elle, la sortie de ce programme devrait être le cube de l'entier entré. Par exemple, 3 entrées -> 27 sorties.

Merci d'avance!


2 commentaires

Il n'y a aucune raison d'utiliser des pointeurs ici. Si vous souhaitez renvoyer un pointeur, utilisez l'adresse de la variable existante ou créez un nouvel int , définissez sa valeur, travaillez avec, puis supprimez .


Son code renvoie un pointeur vers une partie de la pile qui devient indéfinie une fois que vous revenez de la fonction. Comme @dyukha dit si vous voulez renvoyer un pointeur de cette fonction, il devrait être quelque chose sur le tas (créé en utilisant new ()) pas la pile.


3 Réponses :


0
votes

Vous essayez de renvoyer une référence locale inaccessible à l'extérieur de sa portée de déclaration. Vous devez allouer de la mémoire sur le tas en utilisant le mot-clé new et non la pile. Découvrez la différence ici .

void cube3(int &number)
{
   number = (number) * (number) * (number);
}

Notez que je passe le numéro par valeur et non par référence car il n'y a pas de performances de vitesse évidentes / besoin de modifier la valeur de la variable passée. Je ne me soucie pas non plus de créer une variable intermédiaire, newResult , car le résultat de new peut simplement être retourné. Gardez à l'esprit que si je devais créer une valeur intermédiaire newResult , elle serait de type int * . N'oubliez PAS de rendre la mémoire lorsque vous n'avez plus besoin du résultat. Utilisez le mot-clé delete pour désallouer la mémoire. Cela dit, ne vous inquiétez pas de renvoyer un pointeur car l'utilisation du tas est lente et l'allocation manuelle de la mémoire est compliquée.

Voici ce que vous devez utiliser.

int cube(int number)
{
    return number * number * number;
}


0 commentaires

0
votes

result est une variable locale et allouée sur la pile. Lorsque cette fonction prend fin, la mémoire appartenant à result n'est plus valide. Par conséquent, tout pointeur vers cette mémoire n'est pas valide.

Pour une fonction aussi simple, il n'est pas nécessaire de se soucier des pointeurs. Renvoyez simplement une copie du résultat par valeur.

int cube(int *number)
{
    int result = (*number) * (*number) * (*number);
    return result;
}


0 commentaires

0
votes

Il s'agit d'une étendue de variables.

1. Variable globale.

Le "résultat" est une variable locale qui ne peut pas être consultée ou utilisée en dehors du bloc {and}. Vous pouvez l'utiliser par une variable globale.

Les variables globales sont déclarées en tête du programme en dehors de toutes les fonctions ou blocs.

int main()
{
    int input_num, n;
    std::cout << "Enter an int: ";
    std::cin >> n;

    input_num = n;
    cube(&n);

    std::cout << "Cube of " << input_num << " is " << result << std::endl;

    cube2(&n);
    std::cout << "Cube of " << input_num << " is " << n << std::endl;

    n = input_num;
    cube3(n);
    std::cout << "Cube of " << input_num << " is " << n << std::endl;

    return 0;
}

En C, vous pouvez passer des paramètres à une fonction par des pointeurs.

void cube3(int &number)
{
   number = (number) * (number) * (number);
}

2. Passer par référence.

En C ++, vous pouvez passer des paramètres à une fonction soit par pointeurs (cube2) soit par coup de code de référence:

void cube2(int *number)
{
    *number = (*number) * (*number) * (*number);
}

Dans une fonction principale:

static int result;
void cube(int *number)
{
    result = (*number) * (*number) * (*number);
}


0 commentaires