您好,我想與2d arrays:
--2d arrays
cArray :: IO (Ptr (Ptr CDouble))
cArray = do
x <- [C.block| double (*)[2] {
double (*ptd)[2] = malloc(sizeof(double[2][2]));
ptd[0][0] = 1.78;
ptd[0][1] = 1.68;
ptd[1][0] = 1.58;
ptd[1][1] = 1.48;
printf("the firstelement is: %f\n", ptd[1][1]);
return ptd;
}|]
return x
然后在另一個函式中:
e <- cArray :: IO (Ptr (Ptr CDouble))
e1 <- peekElemOff e 0 :: IO (Ptr CDouble)
e2 <- peekElemOff e1 0 :: IO CDouble
print e2
這總是會導致段錯誤。
對于一維陣列,我沒有問題。
誰能給我一個提示?
uj5u.com熱心網友回復:
AC 2D 陣列實際上只是一個 1D 陣列,在其范圍內,編譯器會跟蹤行長度以計算 2D 索引。如果轉換為Ptr (Ptr CDouble). AC 2D 陣列與陣列陣列 2D 陣列不同——后者通常是鋸齒狀陣列,但您也可以通過僅兩次分配更有效地獲得這樣的陣列——一次分配內容,一次分配指向每個陣列的指標排。
cArray :: IO (Ptr (Ptr CDouble))
cArray = [C.block| double** {
int n = 2, m = 2;
double* arr = malloc(sizeof(double[n*m]));
double** ptd = malloc(sizeof(double*[n]));
for (int i=0; i<2; i)
ptd[i] = &(arr[i*m]);
ptd[0][0] = 1.78;
ptd[0][1] = 1.68;
ptd[1][0] = 1.58;
ptd[1][1] = 1.48;
printf("the firstelement is: %f\n", ptd[0][0]);
return ptd;
}|]
正如您自己記得的那樣,C 分配的記憶體最終需要再次清理。Haskell 垃圾收集器本身無法為您執行此操作,但是您可以使用 aForeignPtr而不是 raw來掛鉤它Ptr。
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE QuasiQuotes #-}
import Language.C.Inline as C
import Foreign.Ptr
import Foreign.ForeignPtr
import Foreign.Storable
C.include "<stdio.h>"
C.include "<stdlib.h>"
cArray :: IO (ForeignPtr (Ptr CDouble))
cArray = do
x <- [C.block| double** {
int n = 2, m = 2;
double* arr = malloc(sizeof(double[n*m]));
double** ptd = malloc(sizeof(double*[n]));
for (int i=0; i<2; i)
ptd[i] = &(arr[i*m]);
ptd[0][0] = 1.78;
ptd[0][1] = 1.68;
ptd[1][0] = 1.58;
ptd[1][1] = 1.48;
printf("the firstelement is: %f\n", ptd[0][0]);
return ptd;
}|]
let finalizer = [C.funPtr| void free2Darray(double** ptd) {
free(ptd[0]);
free(ptd);
}|]
newForeignPtr finalizer x
main = do
cArray >>= (`withForeignPtr` \e -> do
e1 <- peekElemOff e 0
e2 <- peekElemOff e1 0
print e2
)
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/348669.html
上一篇:二叉搜索樹中的搜索元素
