-1

I've created a structure with three attributes of a planet. Then, I've created a function which creates a new planet - it's part of a larger application, but it's just a function that assigns the function parameters to some struct variables, then return the structure.

It's actually a snippet of code that I'm trying to understand better. I'm trying to grasp the concept of pointers and dynamic memory.

#include <iostream>
#include <string.h>

using namespace std;


typedef enum {
    NEPTUNE_LIKE,
    GAS_GIANT,
    TERRESTRIAL,
    SUPER_EARTH,
    UNKNOWN
}PlanetType;

typedef struct {
    char name[30];
    PlanetType type;
    float distanceToEarth;
}Planet;

Planet createPlanet(char myname[], PlanetType mytype, double mydistance)
{
    Planet pl;
    strcpy_s(pl.name, myname);
    pl.type = mytype; 
    pl.distanceToEarth = mydistance;
    return pl;
}

char* getName(Planet* p)
{
    return p->name;
}

PlanetType getType(Planet* p)
{
    return p->type;
}

double getDistance(Planet* p)
{
    return p->distanceToEarth;
}

int main()
{
    char s[30] = "Nume";
    static Planet* pl = new Planet();
    *pl = createPlanet(s, UNKNOWN, 345);
    cout << getType(pl) << endl;
    return 0;
}

My question is: what's the purpose of static Planet* pl = new Planet() and why doesn't the program run without it? How is it possible to have a variable pl that points to an entire function? I see the logic behind why a variable would point to an integer for example, but I can't understand what happens in the above case.

  • Do you want to understand what you are doing?:) – Vlad from Moscow Mar 27 '20 at 21:07
  • 1
    I don't even see any reason for `pl` to be a pointer to begin with. Also, it doesn't "point to an entire function", it points to a single `Planet` object. The syntax `new Planet()` dynamically allocates a `planet` object and default initializes it. – Some programmer dude Mar 27 '20 at 21:08
  • 1
    `pl` doesn't point to a function. It points to a `Planet` object. `static` variables local to `main` are pointless, `static` has no effect here. You seem very confused about something, but I don't know what exactly. Edit : You may be mixing C and C++ resources. If you are following tutorials, be certain that they are C++ and not C tutorials. Try to only use resources that were made *at least* after 2011. – François Andrieux Mar 27 '20 at 21:10
  • I also don't see the meaning of the global functions you have, or why you use `typedef`. Please invest in [some good boks](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list/388282#388282) and learn about constructors and member functions. – Some programmer dude Mar 27 '20 at 21:10
  • @Someprogrammerdude It's because this is C with `std::cout` on top. – François Andrieux Mar 27 '20 at 21:11
  • Just some inept code. `Planet pl = createPlanet(...)` is enough, or even `auto pl = createPlanet(...)`. That pointer and the memory allocation that leaks are useless. – Maxim Egorushkin Mar 27 '20 at 21:13
  • @FrançoisAndrieux Thank you so much for help! I'm confused indeed, but I really struggle with OOP and nothing makes sense for me now, that's why it's difficult for me even to express my problems :) – Severienne Bianca Mar 27 '20 at 22:13

1 Answers1

3

what's the purpose of static Planet* pl = new Planet()

Planet is a struct. new returns a pointer to a type; here, you're calling the default Planet constructor generated by the compiler. new allocates memory for an empty Planet, and returns a pointer to that memory.

As mentioned in the comments, there's no need of static here because pl will never be returned to a calling function.

How is it possible to have a variable pl that points to an entire function?

What function do you think it points to? In C++, the form

a = f();

means f is executed and returns a value assigned to a.

I'm trying to grasp the concept of pointers and dynamic memory.

At this stage of the game I recommend trying to solve the problems you're addressing yourself to without dynamic memory. C++ is much easier to understand when you work with value semantics. The minute you introduce pointers, you have a whole new level of complexity. When you know you can't do what you want by passing objects by value, then it'll be time to roll up your sleeves with new and delete. By that time, you'll have some basic syntax under your belt, and it won't seem so mysterious.

I rewrote your program, converting Planet to a class, and moving the functions that relate only to Planet members into the class as member functions. I think you'll agree it's simpler and shorter.

#include <iostream>
#include <string>

using namespace std;

enum PlanetType {
    NEPTUNE_LIKE,
    GAS_GIANT,
    TERRESTRIAL,
    SUPER_EARTH,
    UNKNOWN
};

class Planet {
private:
    char name[30];
    PlanetType type;
    float distanceToEarth;
public:
  Planet( const char myname[], PlanetType mytype, double mydistance ) {
    strcpy(name, myname);
    type = mytype; 
    distanceToEarth = mydistance;
  }

  const char * getName() const { return name; }
  PlanetType   getType() const { return type; } 
  double getDistance() const { return distanceToEarth; }
};

int main() {
  Planet planet( "Nume", UNKNOWN, 345 );
  cout << planet.getType() << endl;
  return 0;
}

Benefits:

  • Planet cannot be constructed without its requisite parts.
  • the "get" functions cannot be passed an invalid pointer

For extra credit, remove the use of C strings and use std::string instead. You'll find that's easier than the alternative: checking the input string length, and throwing an exception if it's too long.

By the way, I intentionally used <string> because C++, and strcpy(3) because idiom. The legend that it's obsolete or deprecated or whatever is wishful thinking at best, if it has no ulterior motive. The millions of uses of strcpy will not disappear in my lifetime or yours.

James K. Lowden
  • 7,574
  • 1
  • 16
  • 31
  • *"The legend that it's obsolete or deprecated or whatever is wishful thinking at best, if it has no ulterior motive."* Most unexpected conspiracy theory I've heard all day. – François Andrieux Mar 27 '20 at 22:22