簡體   English   中英

以這種奇怪的方式創建二維數組的函數的返回類型

[英]Return type of function for this odd way of creating 2D array

這個問題的來源參考: Freaky way of allocating 2D array

我使用了引用帖子的答案中顯示的代碼的改編版本來創建一個字符串數組:

char (*string)[rows] = malloc(sizeof(char [rows][cols]));
memset(string, 0, sizeof(char [rows][cols]));

我意識到對於非常大的數組,這種方法不是最佳的,因為在嘗試分配時,單個大塊的連續內存變得非常昂貴。 但在創建中小型陣列時,優勢可能很有吸引力。 例如。 此方法僅使用一次對malloc()調用來分配單個連續塊內存,因此在使用完后只需要一次對free()調用,使其成為我見過的更慣用的方法的理想替代方法。 (那些使用多次調用malloc()free() ,)

所以,我想把它封裝成一個函數,但到目前為止我還沒有發現什么返回類型是兼容的:

T  CreateStringArray(int rows, int cols)
{
    char (*string)[rows] = malloc(sizeof(char [rows][cols]));
    memset(string, 0, sizeof(char [rows][cols]));

    return T;
}

什么形式的T可以與此函數配合使用?

你可以嘗試這樣的事情:

void * CreateStringArray(int rows, int cols)
{
    char (*string)[cols] = malloc(sizeof(char [rows][cols]));
    memset((void*)string, 0, sizeof(char [rows][cols]));

    return string;
}

int main()
{
    char (*p)[4] = (char (*)[4])CreateStringArray(3, 4);
}

請注意, char (*string)[cols]應使用cols而不是rows定義。 因為string是指向cols元素的一維數組的指針。

延期:

關於為什么使用cols而不是rows詳細信息:

使用時,數組名稱是指向其第一個元素的指針。 例如int arr[5] ,這里的arr是指向a[0]的指針。

盡管int a[rows][cols] ,這里a不是指向a[0][0]的指針,而是指向其類型為int (*)[cols] a[0]的指針

要理解這一點,您必須考慮 C 如何在內存中存儲多維數組? 它實際上是逐行存儲為一維數組。

例如int a[2][3] = {{1, 2, 3}, {4, 5, 6}}; 存儲為1 2 3 4 5 6 ,這里a[0]{1, 2, 3}所以指向a[0]的指針是指向{1, 2, 3}的指針,它是指向 3 的數組的指針可以寫成int (*)[3] => 的整數通常是 `int (*) [cols]'

如果我理解正確,函數應該返回函數內分配的指針,

指針的類型為char (*)[cols]但是當函數被聲明時,函數的返回類型對變量 cols 一無所知。

在這種情況下,函數應該聲明為

void * CreateStringArray(int rows, int cols) )
{
    char (*string)[rows] = malloc(sizeof(char [rows][cols]));
    memset(string, 0, sizeof(char [rows][cols]));

    return string;
}

在調用者中你可以寫

char ( *string )[cols] = CreateStringArray( rows, cols );

char (*)[rows] ,但是這是一個可變修飾類型和對象只(而不是函數),在塊或函數原型范圍沒有任何聯系(不像所有功能),可以有可變修飾類型聲明(C17 6.7.6.2/2)。

因此,您可以為函數的返回類型做的最好的事情是char *void *

但是,您可以使用宏對其進行修補:

void *CreateStringArray_func(int rows, int cols)
{
    char (*string)[rows] = malloc(sizeof(char [rows][cols]));
    memset(string, 0, sizeof(char [rows][cols]));

    return string;
}

#define CreateStringArray(rows, cols) \
    ((char (*)[rows]) CreateStringArray_func(rows, cols))

但在那種特殊情況下,我可能只會使用

#define CreateStringArray(rows, cols) calloc(rows, cols)

您也可以將強制轉換添加到后者,但我根據不強制轉換分配函數結果的原則省略了它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM