#Copy pointer to struct at address

215 messages · Page 1 of 1 (latest)

stuck nimbus
#

If I have a FooStruct** at src - 4, how can I copy this to an allocation dest? I have the following, and it doesn't work:

// src is a BarStruct*
// src - 4 is a FooStruct**
// dest is a BazStruct*
*dest = *(src - 4);
bronze archBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

spare pawn
#

you likely shouldn't copy a FooStruct* to a BarStruct*

stuck nimbus
#

im keeping different datatypes in the same allocation

#

src - 4 is a pointer to a FooStruct**, but src is a BarStruct*

spare pawn
#

in a char* you mean ?

stuck nimbus
#

yeah

spare pawn
#

are you sure the -4 here is correct ?

stuck nimbus
#

yes

spare pawn
#

do you mean 4 char before, or 4*sizeof(FooStruct*) char before?

stuck nimbus
#

4 chars before

spare pawn
#

then it's not src-4

#

unless src is of type char*

stuck nimbus
#

i can show you what im referencing

#

i need to copy the PyDictValues** to a seperate allocation

#

whats wrong with this?

*((PyDictValues***) dest) = ((PyDictValues**) src) - 4;
atomic drift
atomic drift
stuck nimbus
#

yes

atomic drift
stuck nimbus
#

correct

#

i already allocated dest somewhere else

atomic drift
#

gotcha

stuck nimbus
#

i just need to put the pointer in it

atomic drift
stuck nimbus
#

PyObject*

atomic drift
#

is it a triple PyDictValues pointer

#

hm ok

stuck nimbus
#

(src is also a PyObject*)

atomic drift
stuck nimbus
#

this is the python c api

atomic drift
#

Then why are you directly manipulating pointers src -4 the way u are

#

what's your end goal

stuck nimbus
#

im trying to artifically copy a PyObject* to an allocation

#

which in order to do the PyObject* must have attribute values at loc - 4

atomic drift
#

then ur just copying the reference you need a seperate instance

#

read this

stuck nimbus
#

im trying to copy the reference

atomic drift
#

have you tried the Py_INCREF function

stuck nimbus
#

that only increments the refcnt

#

im trying to actually copy the entire pyobject

atomic drift
#

u need to make a deep copy

stuck nimbus
#

copy does not let me copy an object into an allocation

#

is it just plain not possible to set the value from src - 4?

atomic drift
#

u want to duplicate the object's content into somewhere else right

#

somewhere already allocated

#

u can do *dest = copiedObject

#

if dest is a PyObject**

stuck nimbus
#

but then dest wont include that important PyDictValues**

atomic drift
#
typedef struct {
  PyObject* obj;
  PyDictValues **dictValues;
} thing;

Py_INCREF(src);
thing->obj = src;
thing->dictValues = /* Somehow obtain PyDictValues** for src, if src is a dict */;

#

@stuck nimbus im not even sure what u are trying to do atp

#

but this is my guess

stuck nimbus
#

thing would not be a valid python object then

stuck nimbus
atomic drift
#

ok

#

that makes more sense

#

i was a lil confused

#

u would need to implement a custom constructor

#

which would duplicate the contents of ur object

#

but im not sure how

#

u might want to ask someone more into python c api

stuck nimbus
#

dest + 4 is the python object part, and dest should be the PyDictValues**

atomic drift
#

no where can i find that PyDictValues is anywhere in the python c api

stuck nimbus
atomic drift
#

have you tried using PyObject_SetAttrString or PyDict_Copy

stuck nimbus
#

neither of those would help me here

#

all i need to do is just copy that pointer to my allocation

#

src - 4 to dest

atomic drift
#

PyObject* src_dict = PyObject_GetAttrString(src, "__dict__");
if (src_dict && PyDict_Check(src_dict)) {
    PyObject* copied_dict = PyDict_Copy(src_dict);
    if (copied_dict) {
        PyObject* dest_obj = *((PyObject**)(dest + 4));
        PyObject_SetAttrString(dest_obj, "__dict__", copied_dict);
        Py_DECREF(copied_dict);
    }
    Py_DECREF(src_dict);
}
#

i found this online asw

#

an example implementation of copying (in your case)

stuck nimbus
#

i dont want to copy the dict

#

i want both objects to point to the same dict

#

which is weird but im more concerned with whether i could than whether i should

atomic drift
#

cant u just explicitly set the__dict__attribute of the second object to be the same as the first?

#

or am i missing something

stuck nimbus
#

__dict__ is stored under PyObject.ob_type->tp_dict

#

which holds the types dict

#

but the instance attributes are stored at obj - 4

atomic drift
#

so do you want to copy the type dict

#

the contents of

stuck nimbus
#

no, the type dict is copied already

atomic drift
#

just the pydictvalues?

stuck nimbus
#

yup

#

which needs to be at dest, and then the PyObject* is at dest + 4

atomic drift
#

after thinking about it for a wihle i might be overthinking it

#

have you tried using memcpy

stuck nimbus
#

i did and it didnt work

#

i probably messed something up though

atomic drift
#
memcpy(*dest, &sourceValues, sizeof(PyDictValues*));
void *objectDest = (char*)*dest + sizeof(PyDictValues*);
memcpy(objectDest, &sourceObject, sizeof(PyObject*));
``` did you try something like this?
#

where sourcevalues is ur src

stuck nimbus
#

i did not

#

lemme try it

#

@atomic drift dest is a PyObject*, not a PyObject**

atomic drift
#

oh

#

hm

#
char *b = (char*) dest;
memcpy(b, your_dict_values, sizeof(PyDictValues*));
memcpy(b + sizeof(PyDictValues*), &your_py_obj, sizeof(PyObject*));
#

try that

stuck nimbus
atomic drift
#

ye

stuck nimbus
#

wouldnt that make it a triple pointer?

atomic drift
#

oh its a double

stuck nimbus
#

im assuming that your_py_obj shouldnt have the addressof either?

#

your_py_object in my case is a PyObject*

atomic drift
#

on your_dict_values

stuck nimbus
#

got it

stuck nimbus
#

ok

atomic drift
#

did it work?

stuck nimbus
#

hmm, src - 4 and dest are different pointers

#

src - 4: 0x78027ecdaf90, dest: 0x59862056c250

atomic drift
#

didn't you say they were the same

#

oh u want them to be the same

#

my b

#

idk if u could achieve that

#

i dont think u can

stuck nimbus
#

why not?

atomic drift
#

at least not the way i set it up

stuck nimbus
#

do they both point to the same PyDictValues*?

atomic drift
#

your_dict_values is copied at the start of dest, so whatever PyDictValues* it was pointing to, now a copy of that pointer is stored at dest.
your_py_obj's address is stored right after that, so you now have a pointer to your_py_obj stored next to it

#

they dont both point to a pydictvalues *

#

one is a pydictvalue * one is a pyobject*

#

thats why im not sure u can do what u want to do

stuck nimbus
#

i think youre overthinking a little

atomic drift
#

you mean what its pointing too?

#

because they aren't the same pointer type

#

one struct could be bigger so -4 isn't guranteed

stuck nimbus
#

dest should be a PyDictValues**, but dest + 4 is a PyObject*

atomic drift
#

so ur saying u have an array of pydictvalues pointers and the 4th one is a pyobject *

stuck nimbus
#

no

atomic drift
#

you mean *(dest + 4) is a pyobject*

stuck nimbus
#

yes

#

or no

atomic drift
#

ah

stuck nimbus
#

dest + 4 itself is a PyObject*

#

and PyDictValues** is at dest

atomic drift
#

so what type is dest

#

pydictvalues** ?

stuck nimbus
#

yes

#

and dest + 4 is a PyObject*

#

the entire dest allocation itself contains multiple types

atomic drift
#

PyDictValues **dest = array of PyDictValues pointers

stuck nimbus
#

no

#

its not an array

#

its a pointer to a pointer to a struct

atomic drift
#

so (PyObject*) (dest + 4) should be a PyObject *

stuck nimbus
#

dest is just a void*, but the value at dest should be a PyDictValues**

atomic drift
#

yea i mis understood u from the start then

#

lol

#

let me re read what u asked

#

so you want to copy a pyobject * allocation to dest + 4

#

correct?

stuck nimbus
#

yes

atomic drift
#

and you are sure dest + 4 holds a pyobject *

#

if you are, then you can just do

PyObject * newObj; // whatever u want to copy over
(PyObject *) *(dest + 4) = newObj;
stuck nimbus
#

and ive already implemented that

atomic drift
#

sorry you need to dereference it because dest + 4 is still a double pointer

stuck nimbus
#

it’s getting that PyDictValues** at dest that i can’t do

atomic drift
#

*(dest + 4) is a PyObj *

stuck nimbus
#

but i need to copy the PyDictValues** from src - 4

atomic drift
#

yea because *(dest + 4) holds a PyObject*

stuck nimbus
#

yup

stuck nimbus
atomic drift
#

does it matter where in dest you put it?

#

if dest is type void** you can just either allocate more space at the end and typecast it to PyDictValues** and directly copy the data there

#

i dont know where u want to put the data specifically in dest from src-4

stuck nimbus
#

it needs to be at the start

atomic drift
#

so the first sizeof(PyDictValues**) bytes?

#

in dest ?

stuck nimbus
#

yes

atomic drift
#

okay

#

that can be achieved

#
void **dest; (ur block of memory);
size_t newSize = sizeof(dest**) + sizeof(PyDictValues**);
PyDictValues **comesFirst; // your memory u want to come first
void** newMemory = malloc(newSize);
memcpy(newMemory, &comesFirst, sizeof(comesFirst));
memcpy((char*)newMemory + sizeof(comesFirst), dest, sizeof(dest));

dest = newMemory; // dest is still ur pointer
#

@stuck nimbus try that

#

this is what that is doing

stuck nimbus
#

src - 4 and dest are still different pointers

atomic drift
#

src is your PyDict** right

stuck nimbus
#

no

#

src is a PyObject*

#

src - 4 is a PyDictValues**

atomic drift
#

why do you need it to be in this specific order anyways?

#

you want src-4 (your pydict) to be the first block of memory right? in dest

#

@stuck nimbus

stuck nimbus
atomic drift
#

are you doing
PyDictValues** stuff = src - 4;

#

and then copying stuff over to dest

#

if not try that ^

stuck nimbus
#

I already tried that yeah

atomic drift
stuck nimbus
#

sorry for late reply

atomic drift
stuck nimbus
#

i dont, cpython does

#

i just get the PyObject* later on

atomic drift
#

they should be the same

atomic drift
#

ill try and replicate the code give me a sec

stuck nimbus
atomic drift
#

the addresses are very close but not the same

#

im not sure if it's because of the type casting or what

stuck nimbus
#

do they point to the same thing?

#

when you dereference them i mean