2013-05-30 101 views
0

我有一個接口功能在我的應用程序:運行時檢查失敗#2 - 圍繞堆棧變量「名稱」已損壞

void addShopToList(Tshp **shpHead){ 
    char* name; 
    Tshp *newshp = NULL; 
    system("cls"); 
    printf("Name: "); 
    scanf("%s[^\n]", &name); 
    fflush(stdin); 
    newshp = addShp(shpHead,name,NULL); 
    if(prompt("Do you want to add some products?")){ 
     addProductMenu(&newshp); 
    } 
} 

,我也得到:

Run-Time Check Failure #2 - Stack around the variable 'name' was corrupted. 

當我分別觸發這些函數(我的意思是像addShp() - >它只是添加一個新的商店到列表),它正常工作。 我不知道如何解決它:/。

回答

4

name未初始化,所以後來當你嘗試走未初始化的指針的地址:

scanf("%s[^\n]", &name); 

它pukes你。所以兩點:

1)char *name = malloc(100); // now it's initialized to something, don't forget to free it later

2)scanf("%s[^\n]", name); // shouldn't use the & for a string in scanf

和第三獎勵點:

3)fflush(stdin);不這樣做。沖洗stdin是根據C11標準未定義的行爲§7.21.5.2第2部分:

ifstream的點到輸出流... fflush函數導致該流的任何未寫入的數據...將被寫入到所述文件; 否則,行爲是不確定的。

在某些系統,Linux是一個你可以在手冊頁看到fflush(),有一個定義的行爲,但它依賴系統使你的代碼可能無法移植。

+0

工作!謝謝 :) – tomdavies

1

你有兩個問題:

首先是要傳遞指針的地址到字符串scanf - 字符串的不是地址。由於scanf調用並不知道,所以它開始讀取數據到您通過它的地址,覆蓋存儲位置name存儲在內存中它(newshp)等等...到時候scanf已完成,誰知道剩下的是什麼?您可以通過在scanf調用中的name之前刪除&來輕鬆解決該問題。

但是後來你偶然發現了另一個重要的問題:目前name是一個指針,指向誰知道 - 其中 - 它是未初始化的。無論它指向哪裏,都不是你的記憶。固定呼叫scanf將覆蓋該內存 - 您不擁有。然後會發生什麼?

解決方案是初始化name以指向您分配的內存。你可以做的是使用類似malloc分配的內存塊,或者,你可以分配堆棧正是如此的空間:

// allocate space for 99 characters (plus 1 space for the null-terminator 
// and initialize the memory to all null characters. 
char name[100] = { 0 }; 

旁註:你應該試着去理解之間的細微差別當你通過&name而不是namescanf會發生什麼情況。這將是一個非常重要的教學練習,幫助您更好地理解指針以及代碼如何轉換爲機器可以理解的內容。

最後,您不應該致電fflush(stdin),因爲這會導致未定義的行爲。這是一件壞事。你認爲函數調用會實現什麼?

相關問題