我有如下的結構:在運行時可以在結構中設置數組的大小嗎?
struct Query {
int pages[];
int currentpage;
};
我想知道是否可以創建結構之後設置該數組的大小。
Query new = malloc(sizeof(struct Query));
在此之後,我會進行一些計算,然後它會告訴我的大小pages[]
必須這樣做。如果pages[]
需要大小爲4,我該如何設置它?
我有如下的結構:在運行時可以在結構中設置數組的大小嗎?
struct Query {
int pages[];
int currentpage;
};
我想知道是否可以創建結構之後設置該數組的大小。
Query new = malloc(sizeof(struct Query));
在此之後,我會進行一些計算,然後它會告訴我的大小pages[]
必須這樣做。如果pages[]
需要大小爲4,我該如何設置它?
變化pages
成員的類型指針。
struct Query {
int *pages;
int currentpage;
};
struct Query *test = malloc(sizeof(struct Query));
if (test != NULL)
{
//your calculations
test->pages = malloc(result_of_your_calcs);
if (test->pages != NULL)
{
// YOUR STUFF
}
else
{
// ERROR
}
}
else
{
// ERROR
}
當你free
你的結構,你必須做的是相反的。
free(test->pages);
free(test);
在C99可以使用Flexible array members:
struct Query {
int currentpage;
int pages[]; /* Must be the last member */
};
struct Query *new = malloc(sizeof(struct Query) + sizeof(int) * 4);
OP表示想要分配結構並在一些計算後分配數組。你應該添加一個'realloc'的例子。我個人認爲,BTW靈活陣列必須被「專家」人員使用。 – LPs
@LPs,我認爲你是對的,但是用不同大小的realloc(比第一個'malloc')更加危險,不是嗎?對於這個具體情況,我認爲OP意味着在運行時不知道數組的大小來分配結構體(struct中只有一個「int」和一個數組,並且「int currentPage」可以存儲在一個臨時變量中'malloc'然後重新分配給'struct'),但我可能是錯的。請原諒我可憐的英語。 –
我同意。這個特定的情況可以像你描述的那樣工作我不認爲'realloc'比使用'malloc'更危險。我的意思是:你必須知道你在使用靈活數組做什麼。 +1 – LPs
最好的解決辦法是使用指針int
,而不是陣列。
你需要改變:
int pages[];
到:
int *pages;
,然後動態地分配它像這樣:
Query *new = malloc(sizeof(struct Query));
if (new == NULL)
printf ("Error\n");
else
{
new->pages = malloc(4*sizeof(int));
if (new->pages == NULL)
printf ("Error\n");
}
否則,如果你想保持你的格式,你將使用C99 m頌。聲明pages
爲你的結構的最後一個成員,是這樣的:
struct Query {
int currentpage;
int pages[];
};
然後執行:
Query *new = malloc(sizeof(struct Query) + 4*sizeof(int));
不應該是'Query * new = ...'? – Shreevardhan
@Shreevardhan是的,我錯過了星號!謝謝,我編輯了我的帖子:) – Marievi
'new-> pages = malloc(4 * sizeof(int));'如果'new'的前一個'malloc'失敗,'會導致分段錯誤。 –
聲明它作爲指針,並使用malloc
事後
struct Query {
int * pages;
int currentpage;
};
. . .
struct Query obj;
obj.pages = malloc(n * sizeof(int)); // n is the length you want
可以使用柔性陣列構件(在@AlterMann's answer詳情)(C99 +)或零長度陣列( GNU C)。
從https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html引用,
零長度數組被允許在GNU C.他們是作爲一個結構的最後一個元素,那確實是一個可變長度對象的標題非常有用:
struct line { int length; char contents[0]; }; struct line *thisline = (struct line *) malloc (sizeof (struct line) + this_length); thisline->length = this_length;
對於標準的C90,鏈接的網站中提到
在ISO C90,你將不得不給
contents
長度爲1,這意味着要麼浪費空間要麼將參數複雜化爲malloc
。
這意味着要使代碼在標準C90/C89中工作,char contents[0];
應該是char contents[1];
。
GCC支持靈活的數組成員,因此沒有任何理由使用零大小的數組。而且你不需要製作惡意代碼 –
是的。但靈活的陣列成員僅在C99 +中是標準的(是的,我知道C89是古老的,但值得一提)。至於演員陣容,我只是複製了鏈接網站的代碼(我知道不需要演員陣容) –
@ M.M:在允許它們的某些實現中,零大小的數組比靈活的數組成員有一些優勢。例如,如果程序員注意到對齊,給定'struct SIZED_ARRAY {int size; int dat [0];}可以通過struct {SIZED_ARRAY arr;}創建一個初始化的實例。 int dat [4];} my_array = {{4},{1,2,3,4}};'。儘管一些C99編譯器提供了有用的擴展,但我不認爲C99本身提供了任何實用的擴展。 – supercat
'int pages [];' - >'int * pages;'然後'malloc'-吃了它。請記住,在整個「免費」結構之前,頁面必須是免費的。 – LPs
在其他語言中,您可以爲結構創建構造函數。不確定與c。但我認爲這是一條可以走的路。 –
讓'pages'成爲一個int指針。這樣,您可以在創建結構後在malloc堆中爲它分配內存。 – nobism