0

the python code i have is pretty simple:

from ctypes import *
from random import randint

class uni(Union):
    _fields_ = [('p', c_char_p),
                ('a', c_longlong)]

#initializing the array of strings
x = ((c_char_p * 3) * 10) ()
for i in range(10):
    for j in range(3):
        x[i][j] = str(randint(100, 999)).encode('utf-8')

#it prints what i expect it to print
for i in range(10):
    for j in range(3):
        print(x[i][j], end = ' ')
    print()
    
print("addresses")
for i in range(10):
    for j in range(3):
        t = uni()
        # getting an integer that points to the string to print string's address
        t.p = x[i][j] 
        print(hex(t.a), end = ' - ')
        print(string_at(t.a), end = ' | ')
    print()

This outputs the following:

b'475' b'912' b'805' 
b'107' b'986' b'191' 
b'389' b'525' b'921' 
b'441' b'869' b'452' 
b'505' b'788' b'571' 
b'111' b'974' b'758' 
b'447' b'975' b'671' 
b'322' b'633' b'332' 
b'924' b'633' b'174' 
b'677' b'611' b'431' 
addresses
0x7fdfbbbcad80 - b'475' | 0x7fdfbbbcad80 - b'912' | 0x7fdfbbbcad80 - b'805' | 
0x7fdfbbbcad80 - b'107' | 0x7fdfbbbcad80 - b'986' | 0x7fdfbbbcad80 - b'191' | 
0x7fdfbbbcad80 - b'389' | 0x7fdfbbbcad80 - b'525' | 0x7fdfbbbcad80 - b'921' | 
0x7fdfbbbcad80 - b'441' | 0x7fdfbbbcad80 - b'869' | 0x7fdfbbbcad80 - b'452' | 
0x7fdfbbbcad80 - b'505' | 0x7fdfbbbcad80 - b'788' | 0x7fdfbbbcad80 - b'571' | 
0x7fdfbbbcad80 - b'111' | 0x7fdfbbbcad80 - b'974' | 0x7fdfbbbcad80 - b'758' | 
0x7fdfbbbcad80 - b'447' | 0x7fdfbbbcad80 - b'975' | 0x7fdfbbbcad80 - b'671' | 
0x7fdfbbbcad80 - b'322' | 0x7fdfbbbcad80 - b'633' | 0x7fdfbbbcad80 - b'332' | 
0x7fdfbbbcad80 - b'924' | 0x7fdfbbbcad80 - b'633' | 0x7fdfbbbcad80 - b'174' | 
0x7fdfbbbcad80 - b'677' | 0x7fdfbbbcad80 - b'611' | 0x7fdfbbbcad80 - b'431' | 

How? how does it store different strings at the same address??

Note: I found this when I was debugging a program that passes a 2d array of strings to C++ shared object. The C++ function is defined as folows:

extern "C" 
void print2d(char*** arr, int len, int inner_len)
{
  std::cout << arr << '\n';   //ok
  std::cout.flush(); 
  std::cout << *arr << '\n';  //ok
  std::cout.flush();
  std::cout << **arr << '\n'; //this segfaults
}

if anyone has any suggestions to fix this, i would be glad to hear them out

4
  • 1
    I think the "surprises" section of the documentation is relevant.
    – molbdnilo
    Commented Nov 15, 2023 at 9:05
  • Yes, accessing a ctypes object’s contents constructs a new python object each time. In this case, because it is temporary, it is created and destroyed in each print, and each time it is created in the same block of memory. Commented Nov 15, 2023 at 9:08
  • 1
    As for the C++ code, the 2D object passed isn’t a char***, but more like(char*)[][3] (in this case). Not sure I got that right. Don’t have a compiler right now to check. Commented Nov 15, 2023 at 9:17
  • yeah, @MarkTolonen seems to be right the memory was laid out contiguously, and I needed an array of pointers. When I changed it's initialization, everything worked that's also the reason why I received segfaults in C++ Commented Nov 15, 2023 at 15:38

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.