首先,我想說我絕對不是 C 編程專家,而且我已經有一段時間沒有這樣做了。
但是我的任務是用 C 撰寫代碼以解決有關組合學的問題。
基本任務是,給定任何單詞,構造一個包含單詞所有可能右移的方表。在這第一步之后還有很多東西,但這是最重要的,也是給我帶來麻煩的。
實際示例:如果單詞是“ababa”,則“二維陣列”應包含:
- 阿巴巴
- 阿巴布
- 巴巴
- 巴布
- 巴巴
由于這個二維陣列的大小總是長度 * 長度(所以如果單詞的長度為 5,則表將是 5x5)我認為要做的是:
- 呼叫傳遞長度作為引數的函式
- 使用 malloc 創建一個 char** 使其大小正確
- 回傳說字符**
- 呼叫另一個函式用字串填充它
我想出了以下代碼,但雖然它實際上在 GDB 在線完美運行,但它在 Code::Blocks 中回傳錯誤。錯誤是:行程終止狀態為 -1073741819
讓我感到困惑的是,當我嘗試除錯它時,在 Code::Blocks 中,代碼實際上是有效的。這是分配陣列的函式:
char** returnTable(int length){
char** rotationTable = malloc(length*sizeof(char));
char* values = calloc((length 1)*(length 1), sizeof(char));
for(int i=0; i<length; i ){
rotationTable[i] = values i*(length 1);
rotationTable[i][0] = '\0';
}
return rotationTable;}
這是用正確的詞填充結構的函式:
void orderedConjugacyClass(char** table, char* word, int length){
//first word copied in the rotationTable
table[0] = strdup(word);
//let's start from the second row
int j = 1;
//p on the last char of the word
char* p = &table[j-1][length-1];
//q on the first
char* q = &table[j-1][0];
//buffer string, 1 for terminating character
char buffer[length 1];
buffer[0] = '\0';
while(j < length){
strncat(buffer, p, 1);
strncat(buffer, q, length-1);
buffer[length] = '\0';
table[j] = strdup(buffer);
p = &table[j][length-1];
q = &table[j][0];
//to cancel and reuse the buffer for next iteration
buffer[0]='\0';
j ;
}
}
在 main 中,我簡單地呼叫了這兩個函式。如果我只限于此,代碼(顯然)不會有問題。但是每當我嘗試訪問表的內容并用 printf 顯示它時,就會出現問題并且輸出在 GDB online 和 CodeBlocks 之間“發散”:
int length = strlen(argv[1]);
char** rotationTable = returnTable(length);
orderedConjugacyClass(rotationTable, argv[1], length);
for(int j=0; j<length; j )
printf("%s\n", rotationTable[j]);
for(int i=0; i<length; i )
free(rotationTable[i]);
free(rotationTable);
return 0;
附加細節:我在 Windows 上,MinGW 編譯器。
感謝您的幫助和理解。
uj5u.com熱心網友回復:
不要這樣做:
SomeType something = malloc(length*sizeof(SomeType));
做這個:
SomeType something = malloc(length*sizeof(*something));
第一個只有在 的兩個用法相SomeType同時才是正確的,并且使它們不同是一個非常容易的錯誤,特別是如果您SomeType在程式開發的某個時刻進行了更改。
在這種情況下,你寫了
char** rotationTable = malloc(length*sizeof(char));
在這里,元素型別是char*但您char在 中使用的sizeof,這導致您分配的空間太少。
如果你寫
char** rotationTable = malloc(length*sizeof(*rotationTable));
你不會有這個問題。
另請注意,您正在預先分配 的元素,rotationTable然后將預先分配的陣列替換為其他陣列。最初分配的指標丟失了,所以你永遠不會釋放它們,所以你有記憶體泄漏。我看不出重點returnTable。只需orderedConjugacyClass創建并回傳陣列。
最后,這是愚蠢的。
strncat(buffer, p, 1);
strncat(buffer, q, length-1);
buffer[length] = '\0';
strncat必須掃描目的地才能找到終點。但你知道終點在哪里。因此,掃描字串所花費的周期完全沒有意義。
buffer[0] = p[0];
memcpy(buffer 1, q, length-1);
buffer[length] = '\0';
另一方面,pandq也有點毫無意義,因為你可以從原始單詞中復制。事實上,你也可以擺脫buffer:
/* Production code should check if malloc succeeded */
char** conjTable(const char* word) {
size_t len = strlen(word);
char** table = malloc(len * sizeof(*table));
for (size_t i = 0; i < len; i) {
table[i] = malloc(len 1);
memcpy(table[i], word len - i, i);
memcpy(table[i] i, word, len - i);
table[i][len] = '\0';
}
return table;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/314993.html
上一篇:從另一個字串創建一個字串,在C中的每個第n個字符之后插入一個字符
下一篇:為什么變數A沒有被復制到變數B?
