[英]Function that returns an array of strings C
有沒有一種方法可以在不使用動態內存分配的情況下從函數返回字符串數組? 該函數是這樣的:
char** modify(char original[1000][1000]){
char result[1000][1000];
// some operations are applied to the original
// the original is copied to the result
return result;
}
在C中,對象具有四個存儲期限(也稱為生存期)之一:靜態,線程,自動和已分配(C 2018 6.2.4 1)。
具有自動持續時間的對象會在函數內部自動創建,並且在函數執行結束時將不復存在,因此您不能使用在函數內部創建的對象返回值。
分配了存儲時間的對象將一直保留到釋放為止,但是您已要求排除這些對象。
線程存儲持續時間可能不適用於您的情況,或者實際上等效於靜態存儲持續時間,我將在下面討論。
這意味着您可以選擇:
因此,典型的解決方案如下所示:
size_t HowMuchSpaceIsNeeded(char original[1000][1000])
{
… Calculate size.
return SizeNeeded;
}
void modify(char destination[][1000], char original[1000][1000])
{
… Put results in destination.
}
安全性的一種變化是:
void modify(char destination[][1000], size_t size, char original[1000][1000])
{
if (size < amount needed)
… Report error (possibly by return value, or program abort).
… Put results in destination.
}
然后,調用者將執行以下操作:
size_t size = HowMuchSpaceIsNeeded(original);
char (*results)[1000] = malloc(size);
if (!results)
… Report error.
modify(results, size, original)
… Work with results.
free(results);
如Davistor 注意到 ,函數可以返回嵌入在結構的陣列。 就C語義而言,這通過返回值而不是對象避免了對象生存期問題。 (該結構的全部內容就是該結構的值。)就實際的硬件實現而言,它在很大程度上等同於上面的調用者通過對象方法。 (這里的推理是基於計算機工作原理的邏輯,而不是基於C規范:為了使函數返回需要大量空間來表示的值,調用者必須向被調用函數提供所需的空間。 )通常,調用方將在堆棧上分配空間並將其提供給被調用的函數。 這可能比malloc
快,但它也可能占用大量堆棧空間。 通常,我們避免使用大量堆棧空間,以避免堆棧溢出。
盡管您不能在C語言中返回數組類型,但是可以返回包含一個數組的struct
:
#include <string.h>
#define NSTRINGS 100
#define STR_LEN 100
typedef struct stringtable {
char table[NSTRINGS][STR_LEN];
} stringtable;
stringtable modify ( const stringtable* const input )
{
stringtable result;
memcpy( &result, input, sizeof(result) );
return result;
}
我通常建議您使用Eric Postpischil的解決方案。 一種可能效率不高的方法是,如果您需要寫入特定的變量或位置。 在這種情況下,您可以傳遞其地址,但是在這里,您需要創建一個大型的臨時數組並將其復制。
您不能返回指向局部變量的指針,因為它們所指向的內存的生存期僅限於范圍。
基本上, result
是指向堆棧分配的數組第一個元素的指針,因此,將其返回並稍后對其取消引用將導致未定義的行為。
要繞過此問題,很少有解決方法。
我在幾個項目中看到了其中一個,但是我不建議這樣做,因為它不安全。
char** modify(char original[1000][1000]){
// `result` is static array, which lifetime is equal to the lifetime of the program
// Calling modify more than one time will result in overwriting of the `result`.
static char result[1000][1000];
return result;
}
另一種方法是將result
指針作為函數參數接收,因此調用方將為其分配存儲空間。
void modify(char original[1000][1000], char (*result)[1000]){
result[0][1] = 42;
//...
}
void main() {
char result[1000][1000];
modify(someOriginal, result);
}
無論如何,我建議您閱讀一些有關C語言以及計算機內存如何工作的體面的書。
如果沒有動態分配,則不能返回指向函數內部分配的內存的指針。 在您的情況下,您將在堆棧中的區域中分配result[1000][1000]
,一旦函數返回,該區域將被釋放。 除了動態分配,您還可以選擇將緩沖區作為參數傳遞給函數:
void modify(char original[1000][1000], char result[][]) { ... }
現在,必須將result
矩陣分配到modify
函數之外,並且其生存期將不取決於函數的生存期。 基本上,您向函數傳遞一個已經分配的矩陣,該矩陣將在其中寫入結果。
您可以使用從第一個字符串開始到最后一個字符串結束的鏈表。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.