简体   繁体   English

将指针传递给C中的递归函数

[英]passing pointer to recursive function in C

I'm just starting on the road the learning C, and ran into some difficulty: 我刚刚开始学习C语言,遇到了一些困难:

The code listed below is giving me the following error: 下面列出的代码给我以下错误:

Attaching to program: `/workfolder/cocoa/c_stuff/bookshelf/build/Debug/bookshelf', process 1674. 附加到程序:“ / workfolder / cocoa / c_stuff / bookshelf / build / Debug / bookshelf”,过程1674。
Cannot access memory at address 0xa0df194 无法访问地址0xa0df194的内存
Cannot access memory at address 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;
}

The code compiles properly, and the function runs fine the first time (all the questions get asked and the struct receives the data); 代码正确编译,并且该函数在第一次运行时运行良好(所有问题都被询问,并且结构体接收到数据); but when the user types 'y' to add another book, the mem error occurs. 但是,当用户键入“ y”以添加另一本书时,会出现内存错误。

Any ideas where the error is happening? 有什么错误发生的主意吗?

Thanks in advance! 提前致谢!

You've only ever allocated memory for the first book in main - after that it tries to write to the next slot in the array, which doesn't point to an allocated block of memory, giving you a seg-fault. 您只为main中的第一本书分配了内存-之后,它将尝试写入数组中的下一个插槽,该插槽不指向已分配的内存块,从而给您带来段错误。 You're going to have to allocate memory for each book you want to read in. 您将必须为要阅读的每本书分配内存。

In addition, since C doesn't know how long an array is, you have to pass that information along into function calls. 另外,由于C不知道数组有多长,因此您必须将该信息传递给函数调用。 (And I don't see where you're defining book_count.) (而且我看不到您在哪里定义book_count。)

You might try something along these lines: 您可以尝试以下方法:

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
}

Even better in this situation, would just be using a loop and skipping the whole recursion step. 在这种情况下甚至更好的情况是,将仅使用循环并跳过整个递归步骤。

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用作数组下标之前对其进行定义。

Within main, you allocated on the stack an array of 100 pointers to the Book Structure. 在main中,您在堆栈上分配了100个指向Book结构的指针的数组。 I believe it was your intent to allocate 100 structures and then pass the address to that block of structures to getUserInput 我相信您的意图是分配100个结构,然后将地址传递给该结构块以getUserInput

Change main to: 将main更改为:

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

EDIT: OOPS Missed the single Book malloc mentioned in the earlier post. 编辑:OOPS错过了先前文章中提到的单个Book malloc。 That ones Correct for the first book. 那对第一本书是正确的。 If you edit as above and eliminate the if (book_shelf[0]...) check, you'll accomplish your intended results 如果按上述方式进行编辑,并取消了if(book_shelf [0] ...)检查,那么您将完成预期的结果

  1. You allocate just space for the firstbook, not for the others (malloc in main) 您只为第一本书分配空间,而不为其他书分配空间(main中的malloc)

  2. I guess there is some code missing, no declaration and initialization of book_count 我猜有一些代码丢失,没有对book_count的声明和初始化

  3. You should use loops instead of recursion 您应该使用循环而不是递归

  4. Use not recursion but loops for this kind of repetition 不使用递归而是循环进行这种重复

Recursion is probably overkill for this problem where a simple do { ... } while(user keeps answering yes) would do. 对于一个简单的{{} while(用户一直在回答yes)的事情就可以做到的事情,递归可能是多余的。 However the problem you having is in main with your Book *book_shelf[100]. 但是,您的问题主要出在您的Book * book_shelf [100]。 There are several ways you could solve this problem. 有几种方法可以解决此问题。

First change it to an array of Book's like samills suggests: 首先将其更改为类似于samills建议的Book数组:

Book book_shelf[100];

and then change your getUserInput to something like this: 然后将您的getUserInput更改为以下内容:

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

    //...

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

Or you could use your existing code and change you getUserInput function to look something like this and remove the malloc from main: 或者,您可以使用现有代码并更改getUserInput函数,使其看起来像这样,然后从main中删除malloc:

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

props for correct use of the sizeof operator (I see that thing misused so often it makes my eyes bleed). 正确使用sizeof运算符的道具(我经常看到该东西被滥用,使我流血)。

As in Josh's answer, by adding the following lines to your code should make it work: 与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; } 

However, I encourage you not to use the recursive function for getting input. 但是,我建议您不要使用递归函数来获取输入。 Recursive can lead to difficulties in debugging. 递归会导致调试困难。 You may consider using normal loop instead. 您可以考虑使用普通循环。

Note: I'm assuming the book_count is global variable which has been initialized to 0 注意:我假设book_count是已初始化为0的全局变量

thanks a lot for the replies! 非常感谢您的答复!

I realized that I hadn't malloc-ed enough memory to handle more then one element of the struct array (Exactly what Josh is saying). 我意识到我没有分配足够的内存来处理结构数组中的一个以上的元素(正是乔希所说的)。 So essentially: 所以本质上:

Book *book_shelf; 书* book_shelf;

if(book_shelf = (Book*)malloc(sizeof(Book)) == NULL)//exit code if(book_shelf =(Book *)malloc(sizeof(Book))== NULL)//退出代码

so the second time around I would hit a memory issue. 所以第二次遇到内存问题。

thanks again! 再次感谢!

Looks like your still doing it wrong: 看起来您仍然做错了:

Book *book_shelf; 书* book_shelf;

if(book_shelf = (Book*)malloc(sizeof(Book)) == NULL)//exit code if(book_shelf =(Book *)malloc(sizeof(Book))== NULL)//退出代码

book_shelf is only the size of a pointer. book_shelf仅是指针的大小。 When you do the malloc you only allocate one Book at a time. 当您执行malloc时,您一次只能分配一本Book。 This is wrong. 错了 You need to allocate contiguous memory for an array of Book objects all in one instanciation of an array. 您需要在一个数组实例中为Book对象数组分配连续内存。

Like 喜欢

Book book_shelf[100]; 图书book_shelf [100];

not

Book *book_shelf[100]; 图书* book_shelf [100];

or using malloc, use your pointer to point to an array instanciated using 或使用malloc,使用您的指针指向使用实例化的数组
100*malloc(sizeof(Book)). 100 * malloc(sizeof(Book))。

You may get lucky that no other heap memory is allocated in between your malloc(sizeof(Book)) calls and that the memory management system is alocating contiguous memory by default. 您可能会很幸运,在您的malloc(sizeof(Book))调用之间没有分配其他堆内存,并且内存管理系统默认情况下正在分配连续内存。 Also, book_shelf will only point to the last malloced Book structure, not the first one as you indicated you want in your original question. 另外,book_shelf将仅指向最后分配的Book结构,而不是您在原始问题中指示的第一个结构。

Josh is also not allocating enough memory at one time. Josh一次也没有分配足够的内存。 Use a linked list if you want to keep extending elements to the end of your book_shelf one-by-one. 如果要一直将元素一直扩展到book_shelf的末尾,请使用链接列表。

factorial with pointer and recursion 带指针和递归的阶乘

#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