我在我們的開發機器上使用Python C API編寫了一個C封裝器(它是32位,運行32位Python 2.7)。之後我必須將包裝器和C源代碼移動到另一臺64位,運行64位Python 2.6的機器上。在C包裝下面的代碼返回的64位機器上段故障,而不是32位機(它完全存在)上:如何製作一個C封裝(用32位Python編寫)在運行64位Python的新機器上工作?
static PyObject *tide3_tide_hours(PyObject *self, PyObject *args) {
double initHour, z0, delt;
char f_seasonal;
int numHours;
// Parse arguments from Python
if (!PyArg_ParseTuple(args, "ddsid", &initHour, &z0,
&f_seasonal, &numHours, &delt))
return NULL;
// Allocate memory for zhr, which is the output we want
zhr = (double *) malloc ((numHours) *sizeof (double));
// Call the C source code
int value = tide_hours(&tc, initHour,
z0, f_seasonal, numHours, zhr, delt);
// Construct the Python return object by defining
// a new list and looping over zhr
int i;
PyObject *l = PyList_New(0);
if (!l) {
printf("No list \n");
return NULL;
}
for (i=0; i < numHours; i++) {
PyList_Append(l,PyFloat_FromDouble(zhr[i]));
//printf("%f \n",zhr[i]);
}
// Free memory and return the Python list containing zhr to Python
free (zhr);
return l;
}
注意& tc爲只是一個結構I類定義Python並在C包裝的開頭初始化。我想要zhr(由C源代碼中的tide_hours計算),並且如果我取消註釋for循環中的printf語句,可以看到它的正確值。如果我插入:
爲ZHR分配內存後printf("Size of zhr: %d\n",sizeof(zhr));
右,我看「4」的32位機器上和「8」 64位機器上。我確信這就是代碼返回分段錯誤的原因,但我無法弄清楚如何阻止這種情況的發生。
我檢查了其餘的C封裝/ Python代碼,並將問題縮小到本節。輸入參數是正確的值和類型。如前所述,zhr是由tide_hours正確計算和輸出的(如果我在for循環中使用printf),但是與32位到64位交換機的內存分配有關。我不熟悉編寫C包裝器(這是我的第一個包裝器),所以我想知道是否有辦法解決這個問題,或者我甚至沒有想到會導致問題。如果您需要更多代碼,請提前致謝,並告知我們。
我假設你重新編譯的基礎上,爲'zhr'大小的變化。你有沒有嘗試gdb?啓動程序運行,暫停輸入或睡眠。找到pid,然後運行'sudo gdb'並在gdb shell中輸入'attach'然後'繼續'。當段錯誤發生時,gdb會告訴你在哪裏(並且可能顯示一個指針== 0x0或類似的)。您正在使用'zhr'而沒有確認內存是否真正被分配,並且可能發生故障的位置。 –
「zhr」在哪裏定義? (和[爲什麼你施放'malloc()']的結果?(http://stackoverflow.com/q/605845/296974)?) – glglgl
@RyanP是的,我在新機器上重新編譯。我會嘗試你的建議,看看會發生什麼。 @ glglgl zhr首先被定義爲包裝器頂部的double * zhr,在我發佈的函數之外。 –