簡體   English   中英

將指針傳遞給C中的遞歸函數

[英]passing pointer to recursive function in C

我剛剛開始學習C語言,遇到了一些困難:

下面列出的代碼給我以下錯誤:

附加到程序:“ / workfolder / cocoa / c_stuff / bookshelf / build / Debug / bookshelf”,過程1674。
無法訪問地址0xa0df194的內存
無法訪問地址0xa0df194的內存

// code start

#define MAX_NAME_LENGTH 200
#define MAX_AUTHOR_LENGTH 200
#define MAX_DESCRIPTION_LENGTH 1000
#define MAX_PUBLISHER 200
#define MAX_ISBN 50


//structures<
typedef struct {
    char title[MAX_NAME_LENGTH];
    char author[MAX_AUTHOR_LENGTH];
    char ISBN[MAX_ISBN];
    char description[MAX_DESCRIPTION_LENGTH];
    char publisher[MAX_PUBLISHER];
} Book;


void getUserInput(Book *s[])
{   
    printf("what is the book's title ?\n");
    fgets(s[book_count]->title, MAX_NAME_LENGTH, stdin);

    printf("what is the author's name?\n");
    fgets(s[book_count]->author, MAX_AUTHOR_LENGTH, stdin);

    printf("what is the ISBN?\n");
    fgets(s[book_count]->ISBN, MAX_ISBN, stdin);

    printf("write a short description\n");
    fgets(s[book_count]->description, MAX_DESCRIPTION_LENGTH, stdin);

    printf("what is the book's publisher\n");
    fgets(s[book_count]->publisher, MAX_PUBLISHER, stdin);

    printf("want to add another book ? Y\\N\n");

    book_count++;

    if(tolower(fgetc(stdin)) == 'y') 
    {
        return getUserInput(s);
    } 
    else 
    {
        return;
    }
}


int main (int argc, const char * argv[]) {
    // insert code here...
    Book *book_shelf[100];

    if((book_shelf[0] = (Book *)malloc(sizeof(Book))) == NULL)
    {
        exit(1);
    }

    getUserInput(book_shelf);

    return 0;
}

代碼正確編譯,並且該函數在第一次運行時運行良好(所有問題都被詢問,並且結構體接收到數據); 但是,當用戶鍵入“ y”以添加另一本書時,會出現內存錯誤。

有什么錯誤發生的主意嗎?

提前致謝!

您只為main中的第一本書分配了內存-之后,它將嘗試寫入數組中的下一個插槽,該插槽不指向已分配的內存塊,從而給您帶來段錯誤。 您將必須為要閱讀的每本書分配內存。

另外,由於C不知道數組有多長,因此您必須將該信息傳遞給函數調用。 (而且我看不到您在哪里定義book_count。)

您可以嘗試以下方法:

void getUserInput(Book *s[], int *book_count, int max_book_count)
{
   if (book_count == max_book_count) return; // If we've filled all the slots, we can't add anymore without causing trouble.
   s[book_count] = malloc(sizeof(Book));

   ..

   if(tolower(fgetc(stdin)) == 'y') 
   {
       (*book_count)++;
       getUserInput(s, book_count, max_book_count);
   } 
   return;
}

int main (int argc, const char * argv[]) {
    // insert code here...
    Book *book_shelf[100];

    int book_count = 0;
    getUserInput(book_shelf, &book_count, 100);
    // Make sure to free all the malloc'd data
}

在這種情況下甚至更好的情況是,將僅使用循環並跳過整個遞歸步驟。

int main (int argc, const char * argv[]) {
    // insert code here...
    Book *book_shelf[100];

    char response = 'y';
    int book_count = 0;
    while (book_count < 100 && response == 'y')
    {
        book_shelf = malloc(sizeof(Book));
        response = getUserInput(book_shelf[book_count++]);
    }
    // make sure to free all the allocated data!
}

char getUserInput(Book *book)
{
   // write input straight to book
   printf("what is the book's title ?\n");
   fgets(book->title, MAX_NAME_LENGTH, stdin);

   ...

   return tolower(fgetc(stdin));
}

除非我讀錯了什么,否則您沒有在將book_count用作數組下標之前對其進行定義。

在main中,您在堆棧上分配了100個指向Book結構的指針的數組。 我相信您的意圖是分配100個結構,然后將地址傳遞給該結構塊以getUserInput

將main更改為:

Book book_shelf[100];
...
getUserInput(book_shelf);
...

編輯:OOPS錯過了先前文章中提到的單個Book malloc。 那對第一本書是正確的。 如果按上述方式進行編輯,並取消了if(book_shelf [0] ...)檢查,那么您將完成預期的結果

  1. 您只為第一本書分配空間,而不為其他書分配空間(main中的malloc)

  2. 我猜有一些代碼丟失,沒有對book_count的聲明和初始化

  3. 您應該使用循環而不是遞歸

  4. 不使用遞歸而是循環進行這種重復

對於一個簡單的{{} while(用戶一直在回答yes)的事情就可以做到的事情,遞歸可能是多余的。 但是,您的問題主要出在您的Book * book_shelf [100]。 有幾種方法可以解決此問題。

首先將其更改為類似於samills建議的Book數組:

Book book_shelf[100];

然后將您的getUserInput更改為以下內容:

getUserInput(Book *book_shelf, int offset, int length) {
    if(offset < 0 || offset >= length) {
        return;
    }

    //...

    return getUserInput(book_shelf, offset + 1, length)
}

或者,您可以使用現有代碼並更改getUserInput函數,使其看起來像這樣,然后從main中刪除malloc:

getUserInput(Book *book_shelf) {
     book_shelf[book_count] = (Book*)malloc(sizeof(Book));
     // ...
}

正確使用sizeof運算符的道具(我經常看到該東西被濫用,使我流血)。

與Josh的答案一樣,通過在代碼中添加以下幾行,可以使其正常工作:

 book_count++; if(tolower(fgetc(stdin)) == 'y') { if((book_shelf[book_count] = (Book *)malloc(sizeof(Book))) == NULL) { printf("Cannot allocate memory for Book"); exit(1); } return getUserInput(s); } else { return; } 

但是,我建議您不要使用遞歸函數來獲取輸入。 遞歸會導致調試困難。 您可以考慮使用普通循環。

注意:我假設book_count是已初始化為0的全局變量

非常感謝您的答復!

我意識到我沒有分配足夠的內存來處理結構數組中的一個以上的元素(正是喬希所說的)。 所以本質上:

書* book_shelf;

if(book_shelf =(Book *)malloc(sizeof(Book))== NULL)//退出代碼

所以第二次遇到內存問題。

再次感謝!

看起來您仍然做錯了:

書* book_shelf;

if(book_shelf =(Book *)malloc(sizeof(Book))== NULL)//退出代碼

book_shelf僅是指針的大小。 當您執行malloc時,您一次只能分配一本Book。 錯了 您需要在一個數組實例中為Book對象數組分配連續內存。

喜歡

圖書book_shelf [100];

圖書* book_shelf [100];

或使用malloc,使用您的指針指向使用實例化的數組
100 * malloc(sizeof(Book))。

您可能會很幸運,在您的malloc(sizeof(Book))調用之間沒有分配其他堆內存,並且內存管理系統默認情況下正在分配連續內存。 另外,book_shelf將僅指向最后分配的Book結構,而不是您在原始問題中指示的第一個結構。

Josh一次也沒有分配足夠的內存。 如果要一直將元素一直擴展到book_shelf的末尾,請使用鏈接列表。

帶指針和遞歸的階乘

#include<iostream.h>
#include<conio.h>

int show(int *p)

{

int f;

int x=*p;
if(*p==1)  //boundry checking for recursion

return 1;

else

f=x*show(&(--*p)); //this code is similar to f=x*show(n-1); with non-pointers 

return f;

}

void main()

{

int a=6;

int b=show(&a);

cout<<b;

getch();

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM