Micrified
Micrified

Reputation: 3650

C: My struct's properties don't change when referenced from an Array?

I'm having trouble with an array in C that is supposed to hold several structs I defined earlier;

The Struct:

typedef struct
{
    bool alive; 
    struct Vector velocity;
    struct Vector acceleration;
    struct Coordinate position;
    float mass;
    int ID;
}Sprite;

The Array:

Sprite Sprites[10];

To make creating structs easier, I have a function that creates them for me:

Create Struct Function:

Sprite createNewSpriteWithID(int ID, int Mass)
{
    Sprite newSprite;
    newSprite.ID = ID;
    newSprite.mass = Mass;
    newSprite.velocity = VectorWithZero();
    newSprite.acceleration = VectorWithZero();
    newSprite.alive = 1;
    int index = returnAvailableSpriteIndex();
    if (index < 11 && index > -1){
        Sprites[index] = newSprite;
        printf("Sprite inserted at Index: %d\n",index);
        spriteCount += 1;
    } else {
        printf("Notice: Sprite not added");
    }
    return Sprites[index];  // FIXED MY BAD
}

This function makes me a new Struct, and then I assign values to some of the properties. However, I do not do this to position, because I want to change this myself.

The Problem: The issue is that when I attempt to change the positions myself, they are not reflected in the array.

int main(int argc, const char * argv[]) {

    // Create a test Sprites.
    Sprite Sprite_A;

    // Set Sprite Positions and parameters
    Sprite_A = createNewSpriteWithID(1,300);
    setPositionForSprite(&Sprite_A,100,100);
    printf("\nPOS: %f, %f\n",Sprite_A.position.x,Sprite_A.position.y);
    return 0;
}

I call a function called setPositionForSprite, which assigns a position to the position property of the passed sprite pointer.

Set Position:

void setPositionForSprite(Sprite *S, float x, float y)
{
    S->position.x = x;
    S->position.y = y;
}

This is where the problem becomes apparent. When I sprite the position shortly after assigning it in Main, it comes out as intended

100,100

However, when I print the Sprites[index_of_Sprite_A], it gives me garbage values. Why is this happening?

I can fix it by changing the change-position line inside main to:

setPositionForSprite(&Sprites[0],100,100);

But It is unfeasible as I have to recall what the index was.

Why doesn't changing the properties of my struct variable change them in the array?

Upvotes: 0

Views: 159

Answers (4)

z0lupka
z0lupka

Reputation: 236

Your function createNewSpriteWithID returns an integer value, then you give its address as argument to function setPositionForSprite. That is why you make access to the number, as to the object of your structure..

Upvotes: 2

Sourav Ghosh
Sourav Ghosh

Reputation: 134336

In your createNewSpriteWithID() function, you're returning 1.

Again, Sprite newSprite; is local to createNewSpriteWithID(). You cannot return the address of newSprite, either.

Instead, you need to have a pointer to Sprite, allocate memory dynamically and return that pointer. Along with that, you need to change the return type of createNewSpriteWithID() to Sprite * and collect the same in another Sprite *.

Also, with a definition like Sprite Sprites[10];

if (index < 11 && index > -1){
        Sprites[index]....

is wrong. Array index in c starts from 0. You need to change to

if (index < 10 && index > -1){

EDIT

well, your changes are not reflected in the original array because, from your createNewSpriteWithID() function, you're returning the array element value which is then collected in a local variable inside your main(). When you call setPositionForSprite(), you're passing the address of the local variable in the main(), so the change is being reflected in the local variable in the main(), not in the array element.

To rectify, use a pointer [i.e., return the address of the element in the array], as I suggested above.

Upvotes: 3

David Heffernan
David Heffernan

Reputation: 612963

createNewSpriteWithID returns the struct by value. Which means that a copy is made.

Perhaps you mean to return a pointer to the struct. You could alternatively have createNewSpriteWithID return the index that was chosen.

You also appear to access the array out of bounds. Valid indices are 0 to 9 inclusive.

Upvotes: 2

StenSoft
StenSoft

Reputation: 9609

You change the value in a temporary variable in main, not in the array.

Upvotes: 0

Related Questions