Home > Mobile >  C pointer returning data other than the expected contents, but the data remains the same no matter t
C pointer returning data other than the expected contents, but the data remains the same no matter t

Time:12-25

I have a 2d array, const unsigned long test_tileset[n][8], which I'm trying to load into a struct.

The struct is defined as:

typedef struct DynamicTileset {
    unsigned long **tileset;
    LinkedList* usedTiles;
    short* tilemap;
} DynamicTileset;

and I assign the value using the function:

DynamicTileset* createDynamicTileset(unsigned long **tileset) {
    DynamicTileset* dynamicTileset = malloc(sizeof(DynamicTileset));
    dynamicTileset->tileset = tileset;
    dynamicTileset->usedTiles = createLinkedList();
    dynamicTileset->tilemap = NULL;
    return dynamicTileset;
}

called as:

DynamicTileset* title_tileset = createDynamicTileset(test_tileset);

And verify that title_tileset->tileset == test_tileset.

The problem arises when I try to access any of the tiles from the struct. I can access indices in the original tileset just fine via test_tileset[i][j], but when I try to do the same through title_tileset->tileset[i][j], I get a specific set of seemingly random data every time. I'm guessing I've messed something up with the pointers here, but I can't seem to figure out what. How can I assign one of these tilesets to the struct?

Minimal example:

//You likely want to include these in a separate .c file and include the .h, to prevent the error  
//"multiple definitions" from happening when compiling. I do not know if this happens to others
//or if it is simply my compiler.
const unsigned long test_tileset[1][8] = {
    {   0x12345678,
        0x23456789,
        0x3456789A,
        0x456789AB,
        0x56789ABC,
        0x6789ABCD,
        0x789ABCDE,
        0x89ABCDEF
    }
};

typedef struct Node
{
    int data;
    struct Node *next;
} Node;

typedef struct LinkedList
{
    Node *head;
    Node *tail;
    int size;
} LinkedList;

typedef struct DynamicTileset {
    unsigned long **tileset;
    LinkedList* usedTiles;
    short* tilemap;
} DynamicTileset;


struct LinkedList* createLinkedList() {
    struct LinkedList* list = malloc(sizeof(struct LinkedList));
    list->head = NULL;
    list->tail = NULL;
    list->size = 0;
    return list;
}

DynamicTileset* createDynamicTileset(unsigned long **tileset) {
    DynamicTileset* dynamicTileset = malloc(sizeof(DynamicTileset));
    dynamicTileset->tileset = tileset;
    dynamicTileset->usedTiles = createLinkedList();
    dynamicTileset->tilemap = NULL;
    return dynamicTileset;
}

//this should be in the main file
int main() {
    DynamicTileset* title_tileset = createDynamicTileset(test_tileset);

    if (title_tileset->tileset != test_tileset) {
        printf("tileset pointer is wrong");
    }
    for (int i=0; i<8; i  ) {
        if (title_tileset->tileset[0][i] != test_tileset[0][i]) {
            printf("first tile is wrong");
            break;
        }
    }
}

CodePudding user response:

I added the missing headers and typedefs. Removed the struct name LinkedList and used the typedef name in your code. Then I changed the type of your test_tileset to match your use (both u32/unsigned long, and [][] to **). Added a const cast when you compare the const and non-cost types values. Your code now compiles without warning and prints nothing (success):

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef uint32_t u32;
typedef int16_t s16;

const u32 **test_tileset = (const u32 *[]) {
    (u32 []) {
        0x12345678,
        0x23456789,
        0x3456789A,
        0x456789AB,
        0x56789ABC,
        0x6789ABCD,
        0x789ABCDE,
        0x89ABCDEF
    }
};

typedef struct Node
{
    int data;
    struct Node *next;
} Node;

typedef struct
{
    Node *head;
    Node *tail;
    int size;
} LinkedList;

typedef struct DynamicTileset {
    u32 **tileset;
    LinkedList* usedTiles;
    s16* tilemap;
} DynamicTileset;


LinkedList *createLinkedList() {
    LinkedList* list = malloc(sizeof(*list));
    list->head = NULL;
    list->tail = NULL;
    list->size = 0;
    return list;
}

DynamicTileset* createDynamicTileset(const u32 **tileset) {
    DynamicTileset* dynamicTileset = malloc(sizeof(DynamicTileset));
    dynamicTileset->tileset = (u32 **) tileset;
    dynamicTileset->usedTiles = createLinkedList();
    dynamicTileset->tilemap = NULL;
    return dynamicTileset;
}

int main() {
    DynamicTileset* title_tileset = createDynamicTileset(test_tileset);
    if ((const u32 **) title_tileset->tileset != test_tileset) {
        printf("tileset pointer is wrong");
    }
    for (int i=0; i<8; i  ) {
        if (title_tileset->tileset[0][i] != test_tileset[0][i]) {
            printf("first tile is wrong");
            break;
        }
    }
}
  • Related