// Online C compiler to run C program online
#include <stdio.h>/span>
#include <stdlib.h>
char* word(char W[]) {
char *temp = w;
return temp;
}
char** tokens() {
char *one = word("One") 。
char *two = word("wo")。
char *three = word("three") 。
char *four = word("four")。
char *five = word("five")。
char *six = word("six")。
char *seven = word("even")。
char *eight = word("eight")。
char *nine = word("nine") 。
char *ten = word("ten")。
char *eleven = word("ten")。
char *twelve = word("ten")。
char *thirteen = word("ten") 。
char *words[13] 。
words[0] = one;
words[1] = two;
words[2] = three;
words[3] = four;
words[4] = five;
words[5] = six;
words[6] = seven;
words[7] = eight;
words[8] = nine;
words[9] = ten;
words[10] = eleven;
words[11] = twelve;
words[12] = thirteen;
char **pp = words;
return pp。
}
int main() {
//在此寫下C語言代碼。
char **pp = (char **)malloc(13 * sizeof(char) )。)
pp = tokens()。
for (int i = 0; i < 12; i ) {
printf("%s
", *pp)。)
*pp 。
}
// for (; *pp; *pp ) {.
// printf("%s
", *pp);
// }
return 0;
}
我希望代碼能夠列印tokens()方法中包含的每個單詞。然而,在main()的for回圈中,它只列印了:1、2、3、4、null,然后就出現了分段錯誤。如果我使用注釋中的for回圈,它只列印出:一、二、三、四。我是C語言的新手,所以指標還是很混亂的。我希望得到任何幫助。謝謝。
uj5u.com熱心網友回復:
你有相當多的錯誤:
char **pp = (char **)malloc(13 * sizeof(char) )。)
當分配記憶體時,你想分配sizeof(<oneLevelUp>) * numOfElements。 在這種情況下,你要為一個char**進行分配,所以 "一級 "是一個char*。 此外,不需要對malloc的回傳值進行鑄造。 將其改為
char **pp = malloc(13 * sizeof(char*)) 。
最后,最好的做法是在使用sizeof時包含變數名。 這意味著如果變數的型別發生變化,將減少維護作業。
char **pp = malloc(13 * sizeof(*pp)) 。 //首選方法
*pp是一個char*型別。 如果你把它改為
int **pp = malloc(13 * sizeof(*pp)) 。
現在*pp是一個int*型別,無需將sizeof引數從char*改為int*。
其他問題已經在評論和答案中得到了解決。 word基本上什么也沒做,因為它只是回傳傳入它的引數;這個函式肯定會被優化掉。 @AndreasWenzel的答案解釋了tokens的問題所在。 評分最高的答案這里有一個關于回傳指標到區域變數的有趣的軼事。
最后還有一點,即使tokens沒有呼叫UB,你也會因為將pp分配給tokens的回傳值而造成記憶體泄漏。
char **pp = malloc(13 * sizeof(*pp)) 。
if (pp == NULL)
{
// uh oh, we're out of memory, handle the error however you want. 在這個例子中,只是退出。
exit(-1)。
}
// uh oh, 通過做這個賦值,pp不再指向記憶體塊。
//從`malloc`回傳。現在,該記憶體被保留了,沒有任何東西指向
//它。如果我們一次又一次地這樣做,我們的行程將繼續消耗 它。
//記憶體,直到沒有剩余的記憶體。
pp = tokens()。
uj5u.com熱心網友回復:
陣列words的壽命在函式tokens回傳后就結束了。因此,函式tokens回傳一個指向這個物件的指標是沒有意義的,因為這個指標將指向一個不再存在的物件。解除該指標將導致未定義行為(即你的程式可能會崩潰)。
如果您希望函式tokens回傳一個指向有效物件的指標,您必須確保words的生命周期不會結束,例如通過使用動態記憶體分配(即malloc)或者通過使用static關鍵字,將words的生命周期改為靜態。
在你的例子中,最好是洗掉函式tokens,并簡單地在函式main中定義變數words,像這樣:
static const char *const words[] = {
"one", "two", "three", "four", "5" 。
"六"/span>, "七"/span>, "八"/span>, "九"/span>, "十"/span>。
"十一"/span>, "十二"/span>, "十三"/span>.
};
如果你真的想保留函式tokens,那么你可以這樣改寫:
const char *const * tokens( void )
{
static const char *const words[] ={
"one", "two", "three", "four", "5" ,
"六"/span>, "七"/span>, "八"/span>, "九"/span>, "十"/span>。
"十一"/span>, "十二"/span>, "十三"/span>.
};
return words;
}
這樣,函式tokens將回傳一個指向靜態分配物件的指標,該物件具有靜態(無限)壽命。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/322457.html
標籤:
