嗨,我正在嘗試將未知數量的命令列引數存盤到 c 中動態分配的字串陣列中。終端告訴我我有一個 segFault,我已經追蹤到一條 strcpy 行(參見代碼 1。)我嘗試查看其他人的解決方案,但我仍然不確定我做錯了什么,但我相信我有記憶體泄漏。
代碼 1。
for (int j = fileLocCount 1; j < argc; j ){
strcpy(filelist.array[filelist.used], argv[j]);
filelist.used = 1;
if (filelist.used == filelist.size){
for (int i = 0; i < 100; i )
insertArray(&filelist, i);
}
}
//printArray(&filelist);
freeArray(&filelist);
'filelist' 變數是一個名為 Array 的結構
typedef struct {
char **array;
size_t used;
size_t size;
} Array;
并具有功能
void initArray(Array *a, size_t initialSize) {
a->array = (char **) calloc(initialSize, 255);
a->used = 0;
a->size = initialSize;
}
void insertArray(Array *a, int element) {
// a->used is the number of used entries, because a->array[a->used ] updates a->used only *after* the array has been accessed.
// Therefore a->used can go up to a->size
if (a->used == a->size) {
a->size *= 2;
a->array = realloc(a->array, a->size * sizeof(int));
}
a->array[a->used ] = a->array[element];
}
void freeArray(Array *a) {
free(a->array);
a->array = NULL;
a->used = a->size = 0;
}
任何幫助都非常感謝
編輯:calloc 中的 255 位對于除錯來說只是一個例外大的數字,這實際上是一個錯字,并且對于 \0 來說應該是 256 位。我不能只參考 argv[i] 和 argc 的原因是因為我需要將未知數量的檔案路徑(我正在存盤的值)傳遞給另一個 c 檔案中的函式。感謝所有的答案,我真的很感激。
編輯2:剛剛意識到我這樣做很愚蠢,完全忘記了我應該為這里的其他人創建一個 size = argc-(num(command line arguments that are not what I want) 的陣列情況。但它不會浪費我將使用動態陣列進一步下線謝謝你們。
uj5u.com熱心網友回復:
您的記憶體分配錯誤。
對于這樣的情況,單個字串的長度沒有固定限制,您需要所謂的“鋸齒狀陣列”。
請參閱https://en.wikipedia.org/wiki/Jagged_array#:~:text=In computer science, a jagged,edges when visualized as output。
它是一個字符指標陣列,其中每個字符指標指向一個存盤實際字串的字符陣列。
所以有兩個分配步驟:
- 分配字符指標陣列
- 為要存盤的每個字串分配字符陣列
第 1 步將如下所示:
#define INITIAL_NUMBER_OF_POINTERS 8
char** array = calloc(INITIAL_NUMBER_OF_POINTERS, sizeof *array);
if (array == NULL) exit(1);
第 2 步將(對于您要復制的每個字串)如下所示:
size_t sz = strlen(string_to_copy) 1;
array[i] = malloc(sz);
if (array[i] == NULL) exit(1);
strcpy(array[i], string_to_copy);
(注:如果你愿意使用非標準strdup函式 step2 可以寫得更簡單)
之后您可以使用realloconarray來存盤額外的字符指標,即準備更多的字串副本。
uj5u.com熱心網友回復:
你有矛盾(我認為兩者都是錯誤的)?alloc:
a->array = (char **) calloc(initialSize, 255);
a->array = realloc(a->array, a->size * sizeof(int));
a->array是 a char **,所以是一個指向字串的指標(它本身就是一個指向 char 的指標),實作了一個字串陣列,每個字串都是一個字符陣列。
所以我不明白為什么每個指標需要 255 個位元組。
指向 char 的指標陣列中的每個指標(指向 char)都應該是指標的大小。所以你需要initialSize乘以指標的大小
a->array = (char **) calloc(initialSize, sizeof(char *));
然后,您需要分配每個字串本身(現在您只分配了指向它們的指標)
for(int i=0; i<initialSize; i ) a->array[i]=malloc(255*sizeof(char));
(sizeof(char)這里更多是為了代碼的清晰,因為它是1. 但是,你永遠不知道,有一天你的代碼可能必須在 2 個位元組的計算機上編譯char)
所以首先calloc應該是
a->array = (char **) calloc(initialSize, sizeof(char *));
for(int i=0; i<initialSize; i ) a->array[i]=malloc(255*sizeof(char));
而對于realloc,它也有同樣的問題。雖然這一次,不是錯誤地為每個指標分配 255 個位元組,而是為每個指標分配sizeof(int)位元組。
所以,realloc應該是
a->array = realloc(a->array, a->size * sizeof(char *));
for(int i=a->size/2; i<a->size; i ) a->array[i]=calloc(255, sizeof(char));
在這兩種情況下,您的主要問題是缺少字串本身的分配。在第一種情況下,您為指標分配了記憶體。大小錯誤(您為每個指標分配了 255 個位元組,而通常 8 或 4 個就足夠了,即sizeof(char *))。因此,您可能會添加足夠多的記憶體來存盤指標,這只是浪費記憶體。但是,您沒有添加任何記憶體來將字符本身存盤在每個字串中。
在第二種情況下,同樣的事情,但指標錯誤大小的記憶體分配是不同的。你sizeof(int)為每個指標分配了位元組,當你應該分配sizeof(char *). 在那里,在大多數機器上,巧合的是,相同的東西(4 個位元組),或者可能還不夠(4 個位元組而不是 8 個)。
注意
- 我猜你的意思是為每個字串分配 255 個字符(否則為什么這 255 個字符是個謎)
- 我沒有進行分配測驗(
*alloc在繼續之前應該檢查是否回傳 null)。 - 我并沒有真正檢查其余的代碼,因為這似乎是一個主要的段錯誤源。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/516832.html
標籤:数组C指针动态的
上一篇:如何將陣列指標傳遞給函式
下一篇:使用指標分配特定的記憶體地址
